web-dev-qa-db-fra.com

Accéder à une propriété de modèle dans un fichier javascript?

Est-il possible d'accéder à une propriété Model dans un fichier Javascript externe?

par exemple. Dans le fichier "somescript.js"

var currency = '@Model.Currency';
alert(currency);

À mon avis

<script src="../../Scripts/somescript.js" type="text/javascript">

Cela ne semble pas fonctionner, mais si je mets le javascript directement dans la vue à l'intérieur des balises de script, cela fonctionne-t-il? Cela signifie qu'il faut mettre le code dans la page tout le temps au lieu de charger le fichier de script externe comme ceci:

@model MyModel;

<script lang=, type=>
var currency = '@Model.Currency';
alert(currency);
</script>

Y a-t-il un moyen de contourner cela?

16
BlueChippy

Il n'y a aucun moyen d'implémenter le code MVC/Razor dans les fichiers JS.

Vous devez définir des données variables dans votre code HTML (dans les fichiers .cshtml). Ce concept est OK et ne viole pas la séparation des problèmes (code HTML généré par le serveur par rapport au code de script client) car, si vous y réfléchissez, ces valeurs de variable sont: une préoccupation de serveur.

Jetez un coup d’œil à cette solution de contournement (partielle mais agréable): Utilisation du fichier Javascript intégré dans un fichier Javascript dans le cadre MVC

9
Ofer Zelig

J'ai abordé ce problème en utilisant des attributs de données, ainsi que jQuery. Cela rend le code très lisible, et sans la nécessité de vues partielles ou de l'exécution de javascript statique à l'aide d'un ViewEngine. Le fichier JavaScript est entièrement statique et sera mis en cache normalement.

Index.cshtml:

@model Namespace.ViewModels.HomeIndexViewModel
<h2>
    Index
</h2>

@section scripts
{
    <script id="Index.js" src="~/Path/To/Index.js"
        data-action-url="@Url.Action("GridData")"
        data-relative-url="@Url.Content("~/Content/Images/background.png")"
        data-sort-by="@Model.SortBy
        data-sort-order="@Model.SortOrder
        data-page="@ViewData["Page"]"
        data-rows="@ViewData["Rows"]"></script>
}

Index.js:

jQuery(document).ready(function ($) {
    // import all the variables from the model
    var $vars = $('#Index\\.js').data();

    alert($vars.page);
    alert($vars.actionUrl); // Note: hyphenated names become camelCased
});

_Layout.cshtml (facultatif, mais bonne habitude):

<body>
    <!-- html content here. scripts go to bottom of body -->

    @Scripts.Render("~/bundles/js")
    @RenderSection("scripts", required: false)
</body>
11
arserbin3

Ce que vous pouvez faire est de passer les étiquettes de rasoir en tant que variable.

Dans rasoir Fichier>

var currency = '@Model.Currency';
doAlert(currency);

dans le fichier JS>

function doAlert(curr){
   alert(curr);
}
2
Patrick

Ce que j’ai fait, c’est de créer un objet js à l’aide du modèle d’appel de méthode, puis de l’appeler à partir du fichier js externe. Comme js utilise des variables globales, je l’encapsule pour éviter tout conflit avec les autres bibliothèques js. Exemple: Dans la vue 

 @section scripts{
        <script>
            var thisPage = {
                variableOne: '@Model.One',
                someAjaxUrl: function () { return '@Url.Action("ActionName", "ControllerName")'; }            
            };
        </script>
        @Scripts.Render("~/Scripts/PathToExternalScriptFile.js")   
    }

Désormais, à l'intérieur de la page externe, vous pouvez obtenir les données avec une étendue protégée pour vous assurer qu'elles ne sont pas en conflit avec d'autres variables globales dans js.

  console.log('VariableOne = ' + thisPage.variableOne);
  console.log('Some URL = ' + thisPage.someAjaxUrl());

Vous pouvez aussi l'envelopper à l'intérieur d'un module dans le fichier externe pour le rendre encore plus résistant aux chocs. Exemple:

$(function () {
    MyHelperModule.init(thisPage || {});
});

var MyHelperModule = (function () {
    var _helperName = 'MyHelperModule';

    // default values
    var _settings = { debug: false, timeout:10000, intervalRate:60000};    

    //initialize the module
    var _init = function (settings) {

        // combine/replace with (thisPage/settings) passed in
        _settings = $.extend(_settings, settings);

        // will only display if thisPage has a debug var set to true            
        _write('*** DEBUGGER ENABLED ***');             

        // do some setup stuff              

        // Example to set up interval
        setInterval(
            function () { _someCheck(); }
            , _settings.intervalRate
        );
        return this; // allow for chaining of calls to helper  
    };

    // sends info to console for module
    var _write = function (text, always) {
        if (always !== undefined && always === true || _settings.debug === true) {
            console.log(moment(new Date()).format() + ' ~ ' + _helperName + ': ' + text);
        }
    };

    // makes the request 
    var _someCheck = function () { 
        // if needed values are in settings
        if (typeof _settings.someAjaxUrl === 'function' 
            && _settings.variableOne !== undefined) { 
            $.ajax({
                dataType: 'json'
                , url: _settings.someAjaxUrl()
                , data: {
                    varOne: _settings.variableOne                    
                }
                , timeout: _settings.timeout
            }).done(function (data) {
                // do stuff
                _write('Done');
            }).fail(function (jqxhr, textStatus, error) {                
                _write('Fail: [' + jqxhr.status + ']', true);
            }).always(function () {
                _write('Always');
            });             
        } else {// if any of the page settings don't exist
            _write('The module settings do not hold all required variables....', true);            
        }
    };

    // Public calls
    return {
        init: _init
    }; 

  })();
1
Mike

Essayez JavaScriptModel ( http://jsm.codeplex.com ):

Ajoutez simplement le code suivant à votre action de contrôleur:

this.AddJavaScriptVariable("Currency", Currency);

Vous pouvez maintenant accéder à la variable "Currency" en JavaScript.

Si cette variable doit être disponible sur le site du trou, placez-la dans un filtre. Vous trouverez un exemple d'utilisation de JavaScriptModel à partir d'un filtre dans la documentation.

1
acuntex

Vous pouvez toujours essayer RazorJs. Il est pratiquement impossible de ne pas utiliser un modèle dans vos fichiers js RazorJs

0
ElvisLives