我可以在ScriptBundle中包含的Javascript中使用Razor语法吗?

时间:2014-11-24 15:02:32

标签: javascript asp.net-mvc asp.net-mvc-4 razor scriptbundle

我有一个控件,其功能类似于以下代码:

的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。

5 个答案:

答案 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