1

我有一个具有类似于以下代码的控件:

Javascript

$("#Postcode").autocomplete({
    source: '@(Url.Action("AutocompleteHelper"))'
});

HTML

@Html.EditorFor(model => model.Postcode)


它过去都直接位于 .cshtml 文件中,Url.Action并按预期生成了一个工作 URL。

最近我需要在多个视图中使用它,所以我将 JS 移动到一个单独的 .js 文件中(包装到 aScriptBundle并通过 包含在父视图中@Scripts.Render),并且相应的 HTML 现在呈现为部分视图。

这样做的副作用是不再发生 Razor 转换。我不想Url.Action用硬编码的/<Controller>/AutocompleteHelper字符串替换,所以有没有其他方法可以动态生成和设置这个值?我可以将 Javascript 从包中移出并进入局部视图,但共识似乎是您不应该在局部视图中使用 JS。

4

5 回答 5

4

不,Razor 不会替换捆绑的 JS 文件。自我修改代码通常是一件坏事,所以如果可以的话,我建议永远不要在页面中注入 Javascript 。

只需将值注入data-所需元素的属性并选择它们:

例如

@Html.EditorFor(model => model.Postcode, new {htmlAttributes = new {@class="postcode", data_source = Url.Action("AutocompleteHelper")}})

并仅像这样与类一起使用:

$(".postcode").each(function(){
    $(this).autocomplete({
         source: $(this).data('source')
    });
});

这允许单个代码处理多个邮政编码控件。

于 2014-11-24T17:12:41.310 回答
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 之前需要完成一些事情。

于 2014-11-24T16:37:52.230 回答
3

@PatrickHofman 是正确的。不过,我实际上会遵循他的第二条建议:

另一种选择是仅在页面中声明该变量,并在保持“原样”的 javascript 中使用该变量。

但是,他没有详细说明这一点,所以我想跟进一些额外的建议。您实际上要做的是向全局范围添加一个变量,以便任何外部 JavaScript 都可以访问它。但是,将东西添加到全局范围是危险的,因此您应该为您的应用程序实现一个唯一的命名空间,并将您需要的任何变量添加到该命名空间而不是直接在全局范围中。这减少了命名空间冲突的可能性。因此,在您看来,您将添加如下内容:

<script>
    var MyAwesomeApp = MyAwesomeApp || {};
    MyAwesomeApp.SomeVariable = '@Model.SomeVariable';
</script>
@Scripts.Render("~/bundles/yourscriptbundle")

然后,您可以通过MyAwesomeApp.SomeVariable.

于 2014-11-24T15:35:59.110 回答
3

不,你不能。Razor 引擎不处理 Javascript 文件。

您可以创建一个cshtml“视图”并将代码放入其中并使用此代码将其包含在您的页面中,就像我认为您所做的那样(您不需要为此采取行动):

@Html.RenderPartial("_JsFileName");

这样,它将通过 Razor 引擎并设置好。不幸的是,你不能将它包含在一个包中。

另一种选择是在页面中声明该变量,并在保持“原样”的 javascript 中使用该变量。

于 2014-11-24T15:04:31.303 回答
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

于 2015-02-01T23:48:11.483 回答