Доступ к свойству модели в файле 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
}`