Access a Model property in a javascript file?

后端 未结 7 1422
醉梦人生
醉梦人生 2020-12-17 14:22

Is it possible to access a Model property in an external Javascript file?

e.g. In \"somescript.js\" file

var currency = \'@Model.Currency\';
alert(cu         


        
相关标签:
7条回答
  • 2020-12-17 15:08

    What i did was create a js object using the Method Invocation pattern, then you can call it from the external js file. As js uses global variables, i encapsulate it to ensure no conflicts from other js libraries. Example: In the view

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

    Now inside of the external page you can then get the data with a protected scope to ensure that it does not conflict with other global variables in js.

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

    Also you can wrap it inside of a Module in the external file to even make it more clash proof. Example:

    $(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
        }; 
    
      })();
    
    0 讨论(0)
  • 2020-12-17 15:08

    I had the same problem and I did this:

    View.

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

    External js.

    `function myFunction(model){
       //do stuff
     }`
    
    0 讨论(0)
  • 2020-12-17 15:09

    I tackled this problem using data attributes, along with jQuery. It makes for very readable code, and without the need of partial views or running static javascript through a ViewEngine. The JavaScript file is entirely static and will be cached normally.

    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, but good habit):

    <body>
        <!-- html content here. scripts go to bottom of body -->
    
        @Scripts.Render("~/bundles/js")
        @RenderSection("scripts", required: false)
    </body>
    
    0 讨论(0)
  • 2020-12-17 15:09

    What you could do is passing the razor tags in as a variable.

    In razor File>

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

    in JS file >

    function doAlert(curr){
       alert(curr);
    }
    
    0 讨论(0)
  • 2020-12-17 15:09

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

    Just add the following code to your controller action:

    this.AddJavaScriptVariable("Currency", Currency);
    

    Now you can access the variable "Currency" in JavaScript.

    If this variable should be available on the hole site, put it in a filter. An example how to use JavaScriptModel from a filter can be found in the documentation.

    0 讨论(0)
  • 2020-12-17 15:16

    There is no way to implement MVC / Razor code in JS files.

    You should set variable data in your HTML (in the .cshtml files), and this is conceptually OK and does not violate separation of concerns (Server-generated HTML vs. client script code) because if you think about it, these variable values are a server concern.

    Take a look at this (partial but nice) workaround: Using Inline C# inside Javascript File in MVC Framework

    0 讨论(0)
提交回复
热议问题