我可以在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。

+2

我会推荐*从未*注入JavaScript插入到页面(如果您可以帮助它)。只需将值注入到所需元素的'data-'属性中,然后从JQuery代码中挑选出来。这允许一段代码处理多个控件。 – 2014-11-24 17:08:18

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

您可以创建一个cshtml“查看”,把代码在那里,并使用此代码在您的网页,包括像我想你是(你不需要为这一个动作):

@Html.RenderPartial("_JsFileName"); 

这样,它将通过剃刀引擎和您的设置。不幸的是,你不能将它包含在一个包中。

另一种选择是声明只有该页面中的变量,并使用该内部的JavaScript保持'原样'。

+0

@加里:需要更多帮助? – 2014-11-25 20:52:26

+0

感谢你和其他人的帮助。不幸的是管理层改变了心态,所以我甚至没有机会尝试这些建议。我提出了每个答案,但公平地接受任何特定的解答。 – 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所需要的变量。

+0

感谢您编制代码。有用的补充。 – 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