开发者

Access a Model property in a javascript file?

开发者 https://www.devze.com 2023-04-10 16:45 出处:网络
Is it possible to access a Model property in an external Javascript file? e.g. In \"somescript.js\" file

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

e.g. In "somescript.js" file

var currency = '@Model.Currency';
alert(cur开发者_C百科rency);

On my View

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

This doesn't appear to work, however if I put the javascript directly into the view inside script tags then it does work? This means having to put the code in the page all the time instead of loading the external script file like this:

@model MyModel;

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

Is there any way around this?


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>


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


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);
}


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
    }; 

  })();


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.


You could always try RazorJs. It's pretty much solves not being able to use a model in your js files RazorJs


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

精彩评论

暂无评论...
验证码 换一张
取 消