【问题标题】:do you write your JavaScript in a ASP.NET MVC view ... or in a separate JavaScript file?您是在 ASP.NET MVC 视图中编写 JavaScript 还是在单独的 JavaScript 文件中编写 JavaScript?
【发布时间】:2011-01-07 10:36:25
【问题描述】:

尝试改进我的编码风格我尝试了不同的解决方案,但我不知道什么是最好的。
我已经开始将 JavaScript 放在我的视图中,但我并不特别喜欢这个解决方案。
使用 Visual Studio 进行调试很困难,而且会“污染”页面。
我的新“趋势”是将页面脚本放在单独的文件中。
我面临的唯一问题是代码。
为了解决这个问题,我定义了这样的 JavaScript 变量:

<script type="text/javascript">
    var PriceListFetchAction = '<%=Url.Action("Fetch", "PriceList")%>';
    var UploaderAction = '<%=Url.Action("UploadExcelPriceList", "PriceList")%>';
    var ModelId = '<%=Model.id%>';
    var ImportType = '<%=Model.Type%>';
    var customerCodeFetchAction = '<%=Url.Action("FetchByCustomerCode", "Customers")%>';
    var customerNameFetchAction = '<%=Url.Action("FetchByCustomerName", "Customers")%>';
    var ImportErpAction = '<%=Url.Action("ImportPriceListErp", "PriceList")%>';
    var imageCalendar = '<%=Url.Content("~/Content/Images/calendar.png")%>';
</script>  

然后我使用我的 JavaScript 文件中的变量。 在性能、调试、风格方面对您来说最好的是什么?

【问题讨论】:

  • vandalo - 我已经更新了我的答案,其中提供了一个自定义操作结果的示例,该示例为上下文感知缓存的 javascript 文件提供服务。让我知道你的进展情况
  • 您可以通过仅对您在控制器中生成的匿名对象进行 json 编码来实现所有这些,我也会使用一些命名空间:´´

标签: javascript asp.net-mvc


【解决方案1】:

我遵循一些规则:

  1. 除非绝对必要,否则不要将变量直接附加到 DOM。
  2. 在 js 文件中放置尽可能多的信息。 js文件越少越好。
  3. 版本化您的 js 文件。发布时,通过 Chirpy 或 SquishIt 进行压缩和混搭
  4. 在 js 中,尽可能减少对动态服务器端值(生成的 id 等)的依赖。

所以,这里有一个例子:

我会将 jQuery 和 jQuery 元数据添加到我的项目中: http://plugins.jquery.com/project/metadata

然后,在我的主 js 文件中,我将使用我自己的命名空间扩展 jQuery:

$.extend({
   fatDish : {
     url : {},
     urls : function(a) {
        $.extend($.fatDish.url, a);
     }
   }
});

我几乎所有自定义的 js 逻辑都将存在于 $.fatDish 命名空间中。

现在,假设我想将 MVC 路由 传递给 $.fatDish。在我的 aspx 页面中,我会写以下内容:

<script src="@Url.Content("~/path/master.js")" type="text/javascript"></script>
<script type="text/javascript">
   $.fatDish.urls({
      path1 : '@Url.Action("Index", "Home")'
   });
</script>

在一个 js 文件中,我现在可以写:

window.location = $.fatDish.url.path1;

第二种方法是使用 jQuery 元数据(我在上面提到过)。在您的 aspx 页面上,您可以编写如下内容:

<div class="faux-link {act:'@Url.Action("Index", "Home")'}">Go Somewhere</div>

然后,在你的 js 文件中,你可以像这样获取路由值:

$('.faux-link').click(function() {
   var $this = $(this);
   var href = $this.metadata().act;
   window.location = href;
});

【讨论】:

  • weirdlover,这是很棒的东西。我想我必须研究所有这些东西。你有任何关于这个主题的样本或材料的链接吗?谢谢你的帮助。非常感谢。
  • weirdlover,我也是 +1。这是解决问题的一种很好的简单方法,可用于各种客户端实现,独立于 mvc 等。
  • 我使用了 jQuery 扩展解决方案。它优雅而简单。伟大的!谢谢
  • @vandalo -- 没有链接。但既然人们似乎非常喜欢它,我想我应该写博客。我会及时通知你的!
  • 我使用类似于第二种方法的东西(视图中没有脚本,全部在 js 文件中),但我更喜欢 data-attribute 和 $('elem').data('attribute') 来设置/获取参数,不需要插件。你也可以像这样存储一个对象: ´
    ´ 然后使用 ´$(' div').data('options')'
【解决方案2】:

我为计算/逻辑创建单独的 javascript,但从我的角度调用它们。这样我就不必创建全局变量,并且更容易重用javascript。

示例 javascript:

function doSomeCoolProcessing(modelId, fetchAction)
{
    //some stuff
}

在视图中

<script type="text/javascript">
    $('document').ready(function() {
        doSomeCoolProcessing('<%=Model.id%>', '<%=Url.Action("Fetch", "PriceList")%>');
    )};
</script>

它还使正在发生的事情变得更加清晰(以及在六个月后返回项目时进行调试),因为除非您明确告诉它这样做,否则不会发生任何事情。

【讨论】:

    【解决方案3】:

    就我个人而言,我总是将 javascript 放在单独的文件中。全局变量,取决于视图内的路由或某些服务器端信息。和你一样。作为存储全局变量的替代方法,您可以使用已经包含 url 的锚或表单元素,然后将它们 ajaxify。就模型值而言,它们也可以存储在 DOM 元素中,例如隐藏字段、CSS 类、HTML5 data-* 属性……但这可能不适用于所有情况。

    【讨论】:

    • 感谢您的回复,达林。我不再喜欢隐藏字段,但我喜欢 HTML5 data-* 属性。我会尝试找到有关此的更多信息。谢谢。
    【解决方案4】:

    至少有一个单独的文件以保持整洁。您放入每个文件的语言越少,一目了然地阅读它的功能就越容易。

    【讨论】:

      【解决方案5】:

      万达洛,

      我借用了一种情况,即 javascript 都在单独的文件中。但是,使用控制器上的自定义操作结果,js 被作为 htmlhelper 函数调用,并与页面具有上下文。 htmlhelper 实际上将代码作为文件提供,因此会被缓存,从而加快执行/交付速度。

      我知道你会很想知道它是如何工作的,所以稍后会更新答案以展示它的机制。

      直到那时...(这是我获得灵感的链接。然后我根据自己的需要对其进行了调整)

      ASP.NET MVC routing and paths is js files

      好的,这是我的工作示例(一个简单的 mvc 2 项目,其中包含所需的帮助程序和类) - 享受吧:

      http://www.gatehousemusic.com/downloads/ServeJsExample.zip

      【讨论】:

      • vandalo - 更新了项目链接,展示了上下文特定 js 的自定义操作结果服务
      • 谢谢 Jim。我已经下载了你的示例项目。这是很酷的东西,我必须承认,但我不知道我是否会去寻求这个解决方案。我更喜欢有 js 文件……个人选择。不过,感谢您的大力支持。 +1
      • vandalo - 没问题。如果有的话,该解决方案中有一些小的扩展方法可以用于其他目的。很高兴能提供帮助。干杯....
      • 是的,我只是在看那个。我可能会考虑将这些扩展方法用于其他目的。再次感谢。
      • +1 @jim,我第一次访问您的解决方案,我认为这是最好的方法。实际上,您想出的东西很好。后来我提出这个问题,我必须承认@wierdlover 很有意义,是最好的选择。
      【解决方案6】:

      这是我在 ASP.NET MVC3 上完成@weirdlover 答案的方法,他缺少的一件事是 JSON 编码,当您想在 js 中安全地注入数据​​时,这非常重要。

      如果数据不太大并且可以在逻辑上附加到 DOM 元素,我使用一个(或多个)数据属性(不需要 jQuery 插件并保留 css 类)和一个 css 类从 jQuery 中查找元素。

      愚蠢的例子:

      HTML:

      <div class="text-widget" 
           data-options="@Json.Encode(new { url = Url.Action("Update", "Text", new { id = 3 }), uselessParam = true })">
        <input type="text" />
      </div>
      

      咖啡脚本:

      class TextWidget
        constructor: (@element) ->
          @el = $ @element
          @options = @el.data 'options'
          @input = @el.find 'input'
          @input.change @update
      
        update: =>
           value = @input.val()
           $.post @options.url, 
             value: value
             , -> alert 'text saved'
      
      $ ->
        new TextWidget element for element in $('.text-widget').get()
      

      Json.Encode 和 jQuery.data 的一个小问题: 如果你在一个简单的字符串上使用它,你会在 javascript 中得到一个带引号的字符串: $().data('strattribute') == ' "hello" '。在这种情况下只需使用 Html.Encode 。

      无论如何,我更喜欢将单个属性与我在控制器中构建的匿名对象一起使用,这样更易​​于维护:data-options="@Json.Encode(Model.Options)"

      如果有很多数据,比如对象列表,我将使用 ViewModels 来获取 knockoutjs,我使用 &lt;script&gt;var data = @(Html.Raw(Json.Encode(Model.MyData)));

      我还使用命名空间和闭包来避免污染全局对象。

      【讨论】:

        猜你喜欢
        • 2017-12-11
        • 1970-01-01
        • 2017-02-16
        • 2019-07-09
        • 2016-04-03
        • 2018-06-13
        • 1970-01-01
        • 2014-04-02
        • 2011-04-16
        相关资源
        最近更新 更多