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

时间:2011-02-22 14:51:37

标签: javascript asp.net-mvc

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

$('#@Html.FieldIdFor(model => model.Name)').autocomplete({

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

$.get('@Url.Action("States", "Location")', { country: $(this).val() }, function (json) {

那部分很容易。我知道如何做到这一点,我知道我可以将此代码部分放在部分视图中,并在部分视图中显示我希望代码显示的位置。这不是我想问的问题。

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

我也知道我可以拥有一个可以为JavaScript提供服务的JSController,例如:

<script src="@Url.Action("Script", "JS", { script = "location" })
        type="text/javascript"></script>

此控制器操作可能会因视图呈现而返回JavaScript。

或许我应该停止偏执,只使用普通的.js文件并将元素ID和URL放在那里,如果我更新我的视图模型或视图,我会去更新.js文件。我想知道这是否是.NET的过度工程问题 - 我有兴趣知道人们如何在Rails或django中做到这一点。

所以我真正想要的是一些“最佳实践”策略。你最常做什么?你如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

警告:我对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>

commonstuff.js

$(Stuff.MODEL_FIELD_SELECTOR).autocomplete({...
// (Or `window.Stuff.MODEL_FIELD_SELECTOR`, but unless you redefine `Stuff`
// locally, there's no need to prefix it.)

请注意,我只使用一个全局符号Stuff来包含这些内容,因此您不会过多地污染全局命名空间。

这里的想法是将代码放在一个可缓存的,可重用的中心位置;但是,只需使用动态生成的代码来设置您需要使用的东西的ID。


更新:如果你有几个(甚至很多)这些,我希望你可能会,并且你正在使用一个符号,你知道你是< / em>一个定义,你可以使用对象文字符号来使事情更紧凑:

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

注意关于最后一个; IE7及更早版本在对象文字的末尾(more)阻塞了尾随逗号。

答案 1 :(得分:1)

您可以做的一件事就是远离服务器端模板/视图,然后转到客户端模板/视图。这样,所有控制器都只为json服务,您将直接在浏览器中将json作为viewData绑定到模板。模板可以缓存,因为您将它们作为json对象(例如)提供。这不是一个简单的实现,但是一旦你完成并运行它,它既可以像你以前见过的那样进行扩展和性能。