请建议一种服务包含服务器端代码的JavaScript的策略

请建议一种服务包含服务器端代码的JavaScript的策略,javascript,asp.net-mvc,Javascript,Asp.net Mvc,我认为这是一个常见的场景-我有一个视图,其中我使用HtmlHelper生成一些HTML元素,我还有一个帮助程序扩展,它允许我获取生成的元素的ID,以便我可以在JavaScript中使用它(例如jQuery): 或者在执行Ajax时,我从UrlHelper构建URL字符串,再次使用服务器端代码在页面上放置一些客户端内容: $.get('@Url.Action("States", "Location")', { country: $(this).val() }, function (json) {

我认为这是一个常见的场景-我有一个视图,其中我使用HtmlHelper生成一些HTML元素,我还有一个帮助程序扩展,它允许我获取生成的元素的ID,以便我可以在JavaScript中使用它(例如jQuery):

或者在执行Ajax时,我从UrlHelper构建URL字符串,再次使用服务器端代码在页面上放置一些客户端内容:

$.get('@Url.Action("States", "Location")', { country: $(this).val() }, function (json) {
那部分很简单。我知道如何做到这一点,我知道我可以把这段代码放在局部视图中,并在我希望代码显示的地方呈现局部视图。这不是我想问的

页面标记中包含的代码不会被缓存,这是一件事。另一件事是,有时我需要在几个视图上使用相同的代码,我希望将其保存在一个地方进行维护。单个位置可以是局部视图,但我希望缓存这段代码,理想情况下它会放在一个.js文件中。但是,我们不能在.js文件中使用服务器端代码。关键字为可缓存单个文件

我还知道我可以有一个JSController来服务JavaScript,例如:

<script src="@Url.Action("Script", "JS", { script = "location" })
        type="text/javascript"></script>
警告:我对ASP.Net做的不多。但问题不是ASP.Net特有的,对于所有同时具有服务器端和客户端代码的应用程序来说都是一样的

我可能会让主JavaScript文件使用ID,这样它就可以从变量中获取,并让您的每视图/每页代码为其生成变量。例如:

<script type='text/javascript'>
    if (!window.Stuff) {
        window.Stuff = {};
    }
    window.Stuff.MODEL_FIELD_SELECTOR = '#@Html.FieldIdFor(model => model.Name)';
</script>
<script type='text/javascript' src='commonstuff.js'></script>
请注意,我只使用了一个全局符号
Stuff
,来包含这些内容,因此您不会对全局名称空间造成过多的污染

这里的想法是将代码放在一个可缓存的、中心的、可重用的地方;但是,只需使用动态生成的代码来设置需要处理的对象的ID


更新:如果您有几个(甚至很多)这样的符号,我想您可能会有,并且您使用的是一个您知道自己是定义符号的符号,那么您可以使用对象文字符号使事情更加紧凑:

<script type='text/javascript'>
    window.Stuff = {
        MODEL_FIELD_SELECTOR:  '#@Html.FieldIdFor(model => model.Name)',
        SOME_OTHER_SELECTOR:   '#@SomeOtherThing',
        SOMETHING_ELSE:        '#@SomethingElse',
        // ...
        LAST_ONE:              '#@TheLastOne'
        //                                   ^
        // Important: No trailing comma here |
    };
</script>
<script type='text/javascript' src='commonstuff.js'></script>

window.Stuff={
MODEL_FIELD_选择器:“#@Html.FieldIdFor(MODEL=>MODEL.Name)”,
SOME_OTHER_选择器:“#@SomeOtherThing”,
还有什么:“#@SomethingElse”,
// ...
最后一个:“#@TheLastOne”
//                                   ^
//重要提示:此处没有尾随逗号|
};

注意最后一点;IE7和早期版本在对象文本()的末尾使用了尾随逗号。

您可以做的一件事是远离服务器端模板化/视图,转到客户端模板化/视图。这样,您的所有控制器将只提供json,并且您将该json作为viewData直接绑定到浏览器中的模板。模板可以缓存,因为您可以将它们作为json对象(例如)使用。这不是一个简单的实现,但一旦您安装并运行它,它的可扩展性和性能将达到前所未有的水平。

虽然这也是一个有效的解决方案,但我认为这将是一个过火的解决方案。:)我宁愿尽我所能继续使用ASP.NET MVC助手,它们帮助很大。@Pawel:我同意,在很多情况下这是一种过分的做法,但我已经使用这个解决方案两年了,一旦你运行了它,你就不会想回头了:)@TJ:你在你的项目中使用过这样的解决方案吗?我对其他SO成员证明的真实世界解决方案非常感兴趣。我希望我能更好地使用JavaScript。还有一件事——我认为如果我能“名称空间”这段代码,它会很有用。你怎么认为?而不是window.Stuff可能有com.companyName.Stuff或projectName.Stuff之类的内容?以防有人“塞”我的“窗户”;)@帕维尔:在我的项目中,我做了一些类似的事情,但并不完全相同。我有一个静态文件,然后是一个脚本块(或特定于页面的脚本文件,具体取决于项目),其中只包含初始化,这基本上就是
Stuff
块,初始化标识符列表。但我不使用任何服务器端lib为我创建客户端id,我自己做。重新命名:这就是
东西的本意。:-)但是您当然可以更进一步:
如果(!window.Company){window.Company={};}
那么
window.Company.Page={…}
$(Stuff.MODEL_FIELD_SELECTOR).autocomplete({...
// (Or `window.Stuff.MODEL_FIELD_SELECTOR`, but unless you redefine `Stuff`
// locally, there's no need to prefix it.)
<script type='text/javascript'>
    window.Stuff = {
        MODEL_FIELD_SELECTOR:  '#@Html.FieldIdFor(model => model.Name)',
        SOME_OTHER_SELECTOR:   '#@SomeOtherThing',
        SOMETHING_ELSE:        '#@SomethingElse',
        // ...
        LAST_ONE:              '#@TheLastOne'
        //                                   ^
        // Important: No trailing comma here |
    };
</script>
<script type='text/javascript' src='commonstuff.js'></script>