格式化MVC3视图的JavaScript

时间:2011-09-05 05:36:48

标签: javascript asp.net-mvc-3 coding-style

我已经尝试了许多不同的方法来组织现在特定于每个View的JavaScript,但我还没有找到任何我觉得舒服的方法。无论如何它似乎很乱。可能(并且希望)因为我没有使用JavaScript很长时间,并且有一种很好的方法可以做到这一点。

目前我正在做的是:

在我的布局文件中,除RenderBody外,我还有脚本的RenderSection。本节包含与每个视图相关的所有JavaScript。全局脚本隐藏在它自己的文件中。

在这部分内部有很多不同的JavaScript部分(对于我最大的View目前大约有600行JavaScript):

  • 变量的一些定义和设置不同的设置(jQuery设置等)。
  • 隐藏屏幕上不同的DOM元素,当用户稍后与View交互时,这些元素将变为可见。
  • 链接到DOM元素的不同事件的许多jQuery代码(click / keyup ++)
  • 一些代码重构为方法,因为它们被不同的jQuery事件使用。

我不喜欢的事情主要有两件事:

  • 所有这些代码都放在一个大的代码块中,很难找到我正在寻找的脚本部分。基本上,随着脚本的增长,它变得非常难以维护。
  • 该脚本与View位于同一文件中。我想把脚本放到一个单独的文件中,但我不能,因为我使用了我的模型的不同部分,以及脚本中的一些HtmlHelpers。例如,在我执行一些$ .post调用的地方,我使用@Url.Action('...')将其链接到正确的操作方法,以确保即使我更改路由,我的脚本也会继续工作。 我也使用模型来决定某些元素是否应该隐藏起来或者不是这样(这是一个让它开始隐藏的好方法,还是有更好的方法?即使我不能把它看起来有点hacky我的手指)。:

@if( Model.SomeBoolValue ){
  @:$("#DOMelementID").hide();
}

一些能让我朝着正确方向前进的建议将受到高度赞赏。在失去对自己代码的控制之前,我需要更好地构建这个结构。

2 个答案:

答案 0 :(得分:4)

是的,它可能变得艰难。

以下是我们的工作,并为我们工作(粗体,因为它可能不适合您)。

对于每个View /页面,我们计算出JavaScript需要哪些模型属性才能做出决策(a.k.a“logic”)。

我们在JavaScript的布局中也有一个部分。

然后我们在View /页面中设置一个JavaScript属性,封装这些属性,如下所示:

@section JavaScript {
   <script type="text/javascript">
      yn.yp = {
          someBoolValue: @Model.SomeBoolValue,
          someOtheProp: '@Model.SomeOtherProp'
      }
   </script>
}

yn =您的命名空间,为您的项目/公司绑定全局命名空间。 yp =您设置JS属性的页面。

然后在你的外部JS文件中:

$(function() {
   if (yn.yp.someBoolValue) {
      $("#elementid").hide();
   }
});

这也是非常干净的方式来处理客户端AJAX使用的路由URL。设置像yn.yp.urls这样的属性,并在View中设置URL,然后JS可以轻松访问它们而无需任何硬编码。

总的来说,这里的目标是减少嵌入式页面JavaScript中的服务器端代码。

设置JS需要做出决策的属性,然后让JS自己做出决定。

希望这是有道理的。

答案 1 :(得分:4)

我建议您查看jQuery plugin authoring并根据您将附加到DOM元素的插件整理您的javascript代码。

@Url.Action('...')问题而言,有许多方法可以解决此问题并将脚本外部化为单独的文件。例如,假设您正在AJAX化现有表单或已包含url的ActionLink:

$('#myAnchor').click(function() {
    // use this.href to fetch the url
    $.post(this.href, function(result) {

    });
    return false;
});

现在,如果您只是想在用户点击div时发送一个AJAX请求,那么您总是可以使用HTML5 data- *属性(与ASP.NET MVC 3不显眼的AJAX和验证工作方式相同)来定义DOM元素上的url:

<div id="mydiv" data-url="@Url.Action("Some Action")">click me</div>

现在在一个单独的文件中

$('#mydiv').click(function() {
    var url = $(this).data('url');
    $.post(url, function(result) {

    });
});

如果你按照我关于编写jQuery插件的第一个建议,你的代码将如下所示:

$('#mydiv').myplugin();

现在让我们考虑以下代码段:

@if(Model.SomeBoolValue) {
    @:$("#DOMelementID").hide();
}

因此,从这里看来,您正在使用视图模型属性来显示/隐藏代码的各个部分。好的,这是我建议您:JSON将此模型序列化到视图中,然后您可以开始将值传递给新开发的jQuery插件:

<script type="text/javascript">
     var model = @Html.Raw(Json.Serialize(Model));
     // now configure configure your plugins, for example
     $('#mysection').myplugin({ model: model });
</script>

现在,在您的插件中,您可以访问视图模型的绝对所有属性。

这就是你需要提出的所有内容。所有其他的javascript当然都在单独的javascript文件中,在可重用的jQuery插件中正确组织。