访问 javascript 文件中的模型属性?

发布于 2024-12-07 15:28:54 字数 508 浏览 0 评论 0原文

是否可以访问外部 Javascript 文件中的模型属性?

“somescript.js”文件中,

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

例如,在我的视图上的

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

这似乎不起作用,但是如果我将 javascript 直接放入脚本标记内的视图中,那么它会起作用吗?这意味着必须始终将代码放在页面中,而不是像这样加载外部脚本文件:

@model MyModel;

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

有什么办法解决这个问题吗?

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

e.g. In "somescript.js" file

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

∞琼窗梦回ˉ 2024-12-14 15:28:54

我使用数据属性和 jQuery 解决了这个问题。它使得代码非常可读,并且不需要部分视图或通过 ViewEngine 运行静态 javascript。 JavaScript 文件是完全静态的,并且会正常缓存。

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(可选,但好习惯):

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

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

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>
走过海棠暮 2024-12-14 15:28:54

无法在 JS 文件中实现 MVC/Razor 代码。

您应该在 HTML 中(在 .cshtml 文件中)设置变量数据,这在概念上是可以的,并且不会违反关注点分离(服务器生成的 HTML 与客户端脚本代码),因为如果您考虑一下,这些变量值是服务器问题。

看看这个(部分但很好)的解决方法: 在 MVC 框架中的 Javascript 文件中使用内联 C#

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

抱猫软卧 2024-12-14 15:28:54

您可以做的是将剃刀标签作为变量传递。

在剃刀文件中>

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

在JS文件中>

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

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);
}
分開簡單 2024-12-14 15:28:54

我所做的是使用方法调用模式创建一个 js 对象,然后您可以从外部 js 文件调用它。由于js使用全局变量,我将其封装起来,以确保不会与其他js库发生冲突。
例子:
在外部页面的 Now视图中,

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

您可以获取具有受保护范围的数据,以确保它不会与 js 中的其他全局变量冲突。

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

您还可以将其包装在外部文件的模块内,以使其更加防冲突。
例子:

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

  })();

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

  })();
甜警司 2024-12-14 15:28:54

尝试 JavaScriptModel ( http://jsm.codeplex.com ):

只需将以下代码添加到您的控制器操作中:

this.AddJavaScriptVariable("Currency", Currency);

现在您可以在 JavaScript 中访问变量“Currency”。

如果该变量应该在孔位上可用,请将其放入过滤器中。可以在文档中找到如何从过滤器使用 JavaScriptModel 的示例。

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.

暮年 2024-12-14 15:28:54

你总是可以尝试 RazorJs。它几乎解决了无法在 js 文件中使用模型的问题 RazorJs

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

猫烠⑼条掵仅有一顆心 2024-12-14 15:28:54

我遇到了同样的问题,我这样做了:

查看。

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

外部js。

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

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
 }`
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文