简体   繁体   English

格式化MVC3视图的JavaScript

[英]Formatting of JavaScript for MVC3 views

I have tried many different ways to organize the JavaScript that is specific for each View now, but I have not found any way that I feel comfortable with. 我已经尝试了许多不同的方法来组织现在特定于每个View的JavaScript,但我还没有找到任何我觉得舒服的方法。 It seems messy anyway. 无论如何它似乎很乱。 Probably (and hopefully) that is because I haven't been working with JavaScript very long, and there is a good way of doing this. 可能(并且希望)因为我没有使用JavaScript很长时间,并且有一种很好的方法可以做到这一点。

Currently what I'm doing is this: 目前我正在做的是:

In my Layout file, I have the a RenderSection for scripts in addition to RenderBody. 在我的布局文件中,除了RenderBody之外,我还有脚本的RenderSection。 This section contains all JavaScript relevant for each single view. 本节包含与每个视图相关的所有JavaScript。 The global script is tucked away in it's own file. 全局脚本隐藏在它自己的文件中。

Inside this sections there is a lot of different part of JavaScript (for my biggest View currently there is about 600 lines of JavaScript): 在这一部分中有很多不同的JavaScript部分(对于我最大的View,目前大约有600行JavaScript):

  • Some definitions of variables and setting different settings (jQuery settings among others). 变量的一些定义和设置不同的设置(jQuery设置等)。
  • Hiding different DOM elements on the screen that will be made visible when the user interacts with the View later on. 隐藏屏幕上不同的DOM元素,当用户稍后与View交互时,这些元素将变为可见。
  • A lot of jQuery code for different events linked to DOM elements ( click/keyup++ ) 链接到DOM元素的不同事件的许多jQuery代码(单击/ keyup ++)
  • Some code refactored into methods because they are used by different jQuery events. 一些代码重构为方法,因为它们被不同的jQuery事件使用。

The things I don't like here are mainly two things: 我不喜欢的东西主要有两件事:

  • All this code is put into one big codeblock and it's hard to find the parts of the script I'm looking for. 所有这些代码都放在一个大的代码块中,很难找到我正在寻找的脚本部分。 Basically, it gets quite unmaintainable as the script grows. 基本上,随着脚本的增长,它变得非常难以维护。
  • The script is located in the same file as the View. 该脚本与View位于同一文件中。 I would like to put the script into a seperate file, but I can't since I use different parts of my Model, and some HtmlHelpers inside the script as well. 我想把脚本放到一个单独的文件中,但我不能,因为我使用了我的模型的不同部分,以及脚本中的一些HtmlHelpers。 For example, where I execute some $.post calls, I use @Url.Action('...') to link it to the correct action method to be sure that my script will continue to work even if I change my routing. 例如,在我执行一些$ .post调用的地方,我使用@Url.Action('...')将其链接到正确的操作方法,以确保即使我更改路由,我的脚本也会继续工作。 I also use the Model to decide if some elements should start out hidden or not like this (is this an ok way to make it start out hidden, or is there a better way? It seems kind of hacky even if I can't put my finger on it).: 我也使用模型来决定某些元素是否应该隐藏起来或者不是这样(这是一个让它开始隐藏的好方法,还是有更好的方法?即使我不能把它看起来有点hacky我的手指):

code

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

Some pointers to get me in the right direction would be highly appreciated. 一些指示让我走向正确的方向将受到高度赞赏。 I need to get this better structured before I lose control over my own code. 在失去对自己代码的控制权之前,我需要更好地构建这个结构。

Yep, it can get tough. 是的,它会变得艰难。

Here's what we do, and works for us (in bold, because it may not work for you). 这是我们的工作,并为我们工作 (以粗体显示,因为它可能对您不起作用)。

For each View/page, we work out what model properties are required by the JavaScript in order to make decisions (aka "logic"). 对于每个View /页面,我们计算出JavaScript需要哪些模型属性才能做出决策(也就是“逻辑”)。

We also have a section in the Layout for the JavaScript. 我们在JavaScript的布局中也有一个部分。

We then set a single JavaScript property in the View/page, encapsulating these properties, something like this: 然后我们在View /页面中设置一个JavaScript属性,封装这些属性,如下所示:

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

yn = your namespace, tying the global namespace for your project/company. yn =您的命名空间,为您的项目/公司绑定全局命名空间。 yp = your page that your setting the JS property for. yp =您为其设置JS属性的页面。

Then in your external JS file: 然后在您的外部JS文件中:

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

This is also a very clean way to handle routing URL's to be used by client-side AJAX. 这也是处理客户端AJAX使用的路由URL的一种非常简洁的方法 Setup a property like yn.yp.urls , and set the URL's in there in the View, then the JS can access them easily and without any hard-coding whatsoever. 设置像yn.yp.urls这样的属性,并在View中设置URL,然后JS可以轻松访问它们而无需任何硬编码。

Overall, the goal here is to reduce server-side code in the embedded page JavaScript. 总的来说,这里的目标是减少嵌入式页面JavaScript中的服务器端代码。

Set properties for whatever the JS needs to make decisions, then let the JS make the decisions itself. 设置JS需要做出决策的属性,然后让JS自己做出决策。

Hope that makes sense. 希望有道理。

I would recommend you taking a look at jQuery plugin authoring and organize your javascript code in terms of plugins that you will attach to your DOM elements. 我建议你看看jQuery插件创作,并根据你将附加到DOM元素的插件组织你的javascript代码。

As far as the @Url.Action('...') problem is concerned there are many ways to solve this issue and externalize your scripts into separate files. @Url.Action('...')问题而言,有许多方法可以解决此问题并将脚本外部化为单独的文件。 For example let's suppose that you are AJAXifying an existing form or ActionLink which already contains the url: 例如,假设您正在AJAX化现有表单或已包含url的ActionLink:

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

    });
    return false;
});

Now if you simply wanted to send an AJAX request when a user clicks on a div for example, you could always use HTML5 data-* attributes (the same way ASP.NET MVC 3 unobtrusive AJAX and validation works) to define this url on the DOM element: 现在,如果您只是想在用户点击div时发送一个AJAX请求,那么您总是可以使用HTML5 data- *属性(与ASP.NET MVC 3不引人注目的AJAX和验证工作方式相同)来定义此URL DOM元素:

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

and now in a separate file 现在在一个单独的文件中

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

    });
});

and if you follow my first advice about writing a jQuery plugin your code will look like this: 如果您按照我关于编写jQuery插件的第一个建议,您的代码将如下所示:

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

Now let's consider the following snippet: 现在让我们考虑以下代码段:

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

So from what it seems here you are using the view model properties to show/hide sections of your code. 因此,从这里看来,您正在使用视图模型属性来显示/隐藏代码的各个部分。 OK, here's what I may suggest you: JSON serialize this model into the view and then you can start passing values from it to your newly developed jQuery plugins: 好的,这就是我建议您: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>

Now inside your plugin you will have access to absolutely all properties of your view model. 现在,在您的插件中,您将可以访问视图模型的绝对所有属性。

And that's all that you will need to put in your view. 这就是你需要在你的观点中提出的所有内容。 All the other javascript will be of course in separate javascript files, properly organized in reusable jQuery plugins. 所有其他的javascript当然会在单独的javascript文件中,在可重用的jQuery插件中正确组织。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM