web-dev-qa-db-de.com

Auf eine Model-Eigenschaft in einer Javascript-Datei zugreifen?

Ist es möglich, in einer externen Javascript-Datei auf eine Model-Eigenschaft zuzugreifen?

z.B. In der Datei "somescript.js"

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

Meiner Ansicht nach

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

Dies scheint jedoch nicht zu funktionieren, wenn ich das Javascript direkt in die Ansicht innerhalb der Skript-Tags setze, funktioniert es dann? Dies bedeutet, dass der Code die ganze Zeit in die Seite eingefügt werden muss, anstatt die externe Skriptdatei wie folgt zu laden:

@model MyModel;

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

Gibt es einen Weg, dies zu umgehen?

16
BlueChippy

Es ist nicht möglich, MVC/Razor-Code in JS-Dateien zu implementieren.

Sie sollten variable Daten in Ihrem HTML-Code (in den .cshtml-Dateien) festlegen. Dies ist konzeptionell in Ordnung und verstößt nicht gegen die Trennung von Bedenken (vom Server generierter HTML-Code im Vergleich zu Client-Skriptcode). Wenn Sie darüber nachdenken, sind diese Variablenwerte ein Serveranliegen.

Sehen Sie sich diese (teilweise aber schöne) Problemumgehung an: Verwenden von Inline C # in der Javascript-Datei in MVC Framework

9
Ofer Zelig

Ich habe dieses Problem zusammen mit jQuery mit Datenattributen angegangen. Es sorgt für sehr gut lesbaren Code, ohne dass Teilansichten oder statisches Javascript über eine ViewEngine erforderlich sind. Die JavaScript-Datei ist vollständig statisch und wird normalerweise zwischengespeichert.

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 (optional, aber gute Gewohnheit):

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

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

Was Sie tun können, ist, die Rasiermesser-Tags als Variable zu übergeben.

Im Rasiermesser Datei>

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

in JS-Datei>

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

Was ich getan habe, war ein js-Objekt mit dem Method Invocation-Muster zu erstellen. Dann können Sie es aus der externen js-Datei aufrufen. Da js globale Variablen verwendet, kapsle ich es, um sicherzustellen, dass keine Konflikte mit anderen js-Bibliotheken auftreten. Beispiel: In der Ansicht 

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

Innerhalb der externen Seite können Sie dann die Daten mit einem geschützten Bereich abrufen, um sicherzustellen, dass sie nicht mit anderen globalen Variablen in Js in Konflikt stehen.

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

Sie können es auch innerhalb eines Moduls in die externe Datei packen, um es sogar noch kollisionssicherer zu machen. Beispiel:

$(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

Versuchen Sie JavaScriptModel ( http://jsm.codeplex.com ):

Fügen Sie Ihrer Controller-Aktion einfach folgenden Code hinzu:

this.AddJavaScriptVariable("Currency", Currency);

Nun können Sie in JavaScript auf die Variable "Währung" zugreifen.

Wenn diese Variable an der Bohrungsstelle verfügbar sein sollte, legen Sie sie in einen Filter. Ein Beispiel für die Verwendung von JavaScriptModel aus einem Filter finden Sie in der Dokumentation.

1
acuntex

Ich hatte das gleiche Problem und tat dies:

Aussicht.

`var model = @Html.Raw(Json.Encode(Model.myModel));
 myFunction(model);`

Externe js.

`function myFunction(model){
   //do stuff
 }`
0
Sebastian

Sie könnten immer RazorJs versuchen. Es ist so ziemlich nicht mehr möglich, ein Modell in Ihren js-Dateien verwenden zu können. RazorJs

0
ElvisLives