我有一个控件,其功能类似于以下代码:
的Javascript
$("#Postcode").autocomplete({
source: '@(Url.Action("AutocompleteHelper"))'
});
HTML
@Html.EditorFor(model => model.Postcode)
左边所有人都直接坐在.cshtml文件中,Url.Action
按预期生成了一个工作网址。
最近我需要在许多视图中使用它,所以我将JS移动到一个单独的.js文件中(包装到ScriptBundle
并通过@Scripts.Render
包含在父视图中)和相应的HTML现在呈现为部分视图。
这样的副作用是不再发生剃刀转换。我不希望用硬编码的 /< Controller> / AutocompleteHelper 字符串替换Url.Action
,那么还有其他方法可以动态生成并设置此值吗?我可以将Javascript从包中移出并进入局部视图,但是共识似乎是你不应该在局部视图中使用JS。
答案 0 :(得分:4)
以下是我将mvc路径导入javascript文件的方法......
在.js文件中有一个Initialise函数(你可以根据需要命名)。将路由传递给Initialise函数,然后使用initialise函数将其分配给js文件中其他javascript可访问的变量。
在你看来......
<script>
Initialise(@(Url.Action("AutocompleteHelper")))
</script>
@Scripts.Render("~/bundles/yourscriptbundle")
在你的.js ......
var autoCompleteRoute;
function Initialise(route) {
autoCompleteRoute = route;
}
然后可以在.js文件中使用该路由。我更喜欢这种方法,因为变量被声明并在.js文件中赋值,并在其中使用它。使用setup / initialise函数还可以清楚地表明,在成功运行javascript之前需要完成一些事情。
答案 1 :(得分:4)
不,Razor没有对捆绑的JS文件进行替换。自修改代码通常是一件坏事,所以我建议永远在页面中注入Javascript,如果你能帮助它。
只需将值注入所需元素的data-
属性并选择它们:
e.g。
@Html.EditorFor(model => model.Postcode, new {htmlAttributes = new {@class="postcode", data_source = Url.Action("AutocompleteHelper")}})
只能像这样使用类:
$(".postcode").each(function(){
$(this).autocomplete({
source: $(this).data('source')
});
});
这允许单个代码处理多个邮政编码控件。
答案 2 :(得分:3)
不,你不能。 Razor引擎无法处理Javascript文件。
您可以创建cshtml
&#39;查看&#39;并将代码放在那里,并在页面中使用此代码包含它,就像我认为你做的那样(你不需要采取行动):
@Html.RenderPartial("_JsFileName");
这样,它将通过Razor引擎并且你已经设置好了。不幸的是,您无法将其包含在一个捆绑包中。
另一种选择是在页面中声明仅该变量,并在javascript中使用该变量,而不是&#39;。
答案 3 :(得分:3)
@PatrickHofman是对的。不过,我实际上会遵循他的第二条建议:
另一种选择是在页面中仅声明该变量,并在javascript中使用该变量,而不是“#”;
但是,他没有详细说明,所以我想跟进一些额外的建议。您实际上要做的是向全局范围添加变量,以便任何外部JavaScript都可以访问它。但是,向全局范围添加内容是危险的,因此您应该为应用程序实现唯一的命名空间,并将所需的任何变量添加到该命名空间,而不是直接添加到全局范围。这减少了命名空间冲突的可能性。因此,在您看来,您将添加如下内容:
<script>
var MyAwesomeApp = MyAwesomeApp || {};
MyAwesomeApp.SomeVariable = '@Model.SomeVariable';
</script>
@Scripts.Render("~/bundles/yourscriptbundle")
然后,您可以通过MyAwesomeApp.SomeVariable
访问捆绑包中包含的外部JS中所需的变量。
答案 4 :(得分:1)
我通常做的是@SimonRyan建议的,除了我使用options
对象而不是只传递一个字符串。如果你需要一个,你很快就会需要另一个。因此,对于options
对象,您必须在添加更多参数时进行少量修改。
所以Initalise
调用看起来像这样:
Initialise({
autoCompleteHelperUrl: '@(Url.Action("AutocompleteHelper"))',
anAdditionalUrl: '@(Url.Action("AdditonalUrl"))'
})
我在这里写了一篇更详细的博客文章: http://blog.blanklabs.com/2015/02/aspnet-mvc-refactoring-friendly.html