Доступ к свойству модели в файле JavaScript? - PullRequest
16 голосов
/ 02 октября 2011

Можно ли получить доступ к свойству Model во внешнем файле 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>

Есть ли способ обойти это?

Ответы [ 7 ]

11 голосов
/ 25 сентября 2013

Я решил эту проблему с помощью атрибутов данных вместе с jQuery. Это делает для очень удобочитаемого кода, и без необходимости частичных представлений или запуска статического JavaScript через ViewEngine. Файл 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>
9 голосов
/ 02 октября 2011

Нет способа реализовать код MVC / Razor в файлах JS.

Вы должны установить переменные данные в своем HTML (в файлах .cshtml), и это концептуально нормально и не нарушает разделения интересов (сгенерированный сервером HTML-код сценария клиента), потому что, если вы подумаете об этом, эти значения переменных относятся к серверу.

Взгляните на этот (частичный, но приятный) обходной путь: Использование Inline C # внутри файла Javascript в MVC Framework

2 голосов
/ 04 октября 2011

Что вы можете сделать, это передать теги бритвы как переменную.

В файле бритвы>

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

в файле JS>

function doAlert(curr){
   alert(curr);
}
1 голос
/ 27 июня 2018

Что я сделал, так это создал объект js, используя шаблон вызова метода, затем вы можете вызвать его из внешнего файла js. Поскольку js использует глобальные переменные, я инкапсулирую их, чтобы не было конфликтов с другими библиотеками js. Пример: По мнению

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

  })();
1 голос
/ 08 января 2013

Попробуйте JavaScriptModel (http://jsm.codeplex.com):

Просто добавьте следующий код в действие вашего контроллера:

this.AddJavaScriptVariable("Currency", Currency);

Теперь вы можете получить доступ к переменной «Валюта» в JavaScript.

Если эта переменная должна быть доступна на месте отверстия, поместите ее в фильтр.Пример использования JavaScriptModel из фильтра можно найти в документации.

0 голосов
/ 20 июня 2019

У меня была такая же проблема, и я сделал это:

вид.

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

Внешний JS.

`function myFunction(model){
   //do stuff
 }`
0 голосов
/ 11 ноября 2011

Вы всегда можете попробовать RazorJs.Это в значительной степени решает невозможность использования модели в ваших файлах js RazorJs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...