Доступ к свойству модели в файле JavaScript?

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

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

6 ответов

Решение

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

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

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

Я решил эту проблему с помощью атрибутов данных вместе с 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>

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

@section scripts{
    <script>
        var thisPage = {
            variableOne: function () { return '@Model.One'; },
            variableTwo: function () { return '@ViewBag.Two'; }            
        };
    </script>
    @Scripts.Render("~/Scripts/PathToExternalScriptFile.js")   
}

Теперь внутри внешней страницы вы можете получить данные в защищенной области, чтобы они не конфликтовали с другими глобальными переменными в js.

console.log('VariableOne = ' + thisPage.variableOne());
console.log('VariableTwo = ' + thisPage.variableTwo());

То, что вы могли бы сделать, это передать теги бритвы в качестве переменной.

В бритвенном файле>

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

в файле JS>

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

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

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

this.AddJavaScriptVariable("Currency", Currency);

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

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

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

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

Посмотреть.

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

Внешний js.

`function myFunction(model){
   //do stuff
 }`
Другие вопросы по тегам