我可以在JavaScript包含的ScriptBundle中使用Razor语法吗?
我有一个功能类似于下面的代码控制:我可以在JavaScript包含的ScriptBundle中使用Razor语法吗?
的Javascript
$("#Postcode").autocomplete({
source: '@(Url.Action("AutocompleteHelper"))'
});
HTML
@Html.EditorFor(model => model.Postcode)
它用于将所有直接坐在里面。 cshtml文件和Url.Action
生成一个工作URL作为exp ected。
最近,我需要的若干意见使用这一点,所以我移动JS到一个单独的js文件(包裹成ScriptBundle
和包括在经由@Scripts.Render
父视图)和相应的HTML现在呈现为局部视图。
这样做的副作用是不再发生剃刀变换。我不想用硬编码替换Url.Action
/<控制器>/AutocompleteHelper字符串,那么有没有其他方法可以动态生成并设置此值?我可以将Javascript从包中移动到局部视图中,但共识似乎是你不应该在局部视图中使用JS。
不,你不能。 JavaScript文件不被Razor引擎处理。
您可以创建一个cshtml
“查看”,把代码在那里,并使用此代码在您的网页,包括像我想你是(你不需要为这一个动作):
@Html.RenderPartial("_JsFileName");
这样,它将通过剃刀引擎和您的设置。不幸的是,你不能将它包含在一个包中。
另一种选择是声明只有该页面中的变量,并使用该内部的JavaScript保持'原样'。
@加里:需要更多帮助? – 2014-11-25 20:52:26
感谢你和其他人的帮助。不幸的是管理层改变了心态,所以我甚至没有机会尝试这些建议。我提出了每个答案,但公平地接受任何特定的解答。 – 2014-12-16 06:02:25
@PatrickHofman是正确的。然而,我实际上会遵循他的第二条建议:
另一种选择是仅在页面中声明该变量,并在保持原样的javascript内使用该变量。
但是,他没有详细说明,所以我想跟进一些额外的建议。你将要做的是在全局范围中添加一个变量,以便任何外部JavaScript都可以访问它。但是,将事物添加到全局范围是非常危险的,因此应该为应用程序实现唯一的名称空间,并将所需的所有变量添加到该名称空间,而不是直接添加到全局范围中。这减少了命名空间冲突的可能性。所以,在你看来,你会加入类似以下内容:
<script>
var MyAwesomeApp = MyAwesomeApp || {};
MyAwesomeApp.SomeVariable = '@Model.SomeVariable';
</script>
@Scripts.Render("~/bundles/yourscriptbundle")
然后你就可以访问你在包含在通过MyAwesomeApp.SomeVariable
你的包你的外部JS所需要的变量。
感谢您编制代码。有用的补充。 – 2014-11-24 15:38:04
这里是我拿得到的MVC路径进入我的javascript文件的方法...
在你的.js文件中有一个初始化函数(你可以将其命名为你想要的)。将路由传递给Initialise函数,然后让初始化函数将它分配给一个变量,该变量可以通过js文件中的其他javascript访问。
在你看来...
<script>
Initialise(@(Url.Action("AutocompleteHelper")))
</script>
@Scripts.Render("~/bundles/yourscriptbundle")
在你的.js ...
var autoCompleteRoute;
function Initialise(route) {
autoCompleteRoute = route;
}
路线随后可在.js文件中使用。我更喜欢这种方法,因为变量已被声明并将其赋值给.js文件中要使用的值。使用设置/初始化函数还可以清楚地知道在JavaScript能够成功运行之前需要完成的事情。
不,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')
});
});
这允许单段代码来处理多个邮政编码的控制。
我通常做的是@SimonRyan建议的,除了我使用options
对象而不是只传递一个字符串。如果你需要一个机会,你很快就会需要另一个。因此,使用options
对象时,您必须在添加更多参数时少修改。
所以Initalise
呼叫是这样的:
Initialise({
autoCompleteHelperUrl: '@(Url.Action("AutocompleteHelper"))',
anAdditionalUrl: '@(Url.Action("AdditonalUrl"))'
})
我写了一个更详细的博客文章在这里: http://blog.blanklabs.com/2015/02/aspnet-mvc-refactoring-friendly.html
我会推荐*从未*注入JavaScript插入到页面(如果您可以帮助它)。只需将值注入到所需元素的'data-'属性中,然后从JQuery代码中挑选出来。这允许一段代码处理多个控件。 – 2014-11-24 17:08:18