【问题标题】:How do you structure your web applications to make AJAX and DHTML easier?您如何构建您的 Web 应用程序以使 AJAX 和 DHTML 更容易?
【发布时间】:2012-01-10 21:33:57
【问题描述】:

给定一个 websinte 的结构

<html>
  <head>
    <!-- CSS at the beginning-->
    <link/>
  </head>
  <body>
    <div id="mainContainer">
      <div id="side"></div>
      <div id="content">
         <!-- DHTML awesomeness happens here -->
      </div>
    </div>
    <!-- Scripts at the end -->
    <script/>
    <script>
         /* code that attach the JS logic to the HTML items */
    </script>
  </body>
</html>

使用普通的网络导航,页面完全呈现在 HTML 中,并遵循渐进增强的方法,最后我寻找一些特定的 id 或类,并使用 javascript 和特别是 jQuery 为它们提供动态行为。在下载外部脚本之后,此增强代码发生在正文的最后。

#content 中,发生了很多 jQuery AJAX 交互,其中一些从服务器获取其他部分视图并将它们插入到页面中,但是我必须再次查找这些 id 和类并将 javascript 对象附加到此新元素。

这可能非常麻烦,因为您不想将控制器、事件处理程序或其他任何东西重新应用于已经拥有它们的对象。

到目前为止,我找到的唯一解决方案是放在我的部分视图中:

@if(Request.IsAjaxRequest())
{
   <script> 
       /* code that attach the JS controllers to the HTML items of this view */
   </script>
}

我认为类似的问题会发生,例如当您想要 $('input.date').datepicker() 并且您动态添加新的 &lt;input type="text" class="date"/&gt; 元素时,除非您重新执行 jQuery 语句,否则新元素没有日期选择器。

例如,考虑到在#content 我有一个&lt;input type="text" class="date"/&gt;

  1. 为了让 jQuery datepicer 第一次工作,我必须 在&lt;body&gt; 末尾调用$('input.date').datepicker(), 在外部&lt;script&gt; 声明之后。

  2. 如果页面下载部分视图是新的&lt;input type="text" class="date"/&gt; 元素,我必须将初始化调用放在 ajax 的视图中 来电。

所以我以重复的代码结束,这是我不希望在 JS 中特别想要的,因为我无法像在 C# 中那样轻松地重构代码。

这是上周让我发疯的事情,想知道是否有更好的方法来实现这一点?更好的技术,还是其他整体方法?

您如何构建您的网络应用程序?

亲切的问候。

PS:如果有像.live().delegate() 这样的东西会很好,但不仅与事件有关,不是吗?每次将某些内容添加到 DOM 时,jQuery/浏览器是否会引发任何事件?

【问题讨论】:

  • 就结构而言,我发现初学者使用布局和部分更容易。当我需要一个小部件时,假设要始终如一地渲染,我可以选择 Html.RenderPartial 或 Html.RenderAction 作为我的局部视图。取决于 viewModel 和我所追求的。我尽量避免使用过多的 Jquery,并利用 MVC 来实现它的目的。
  • 除了我漫不经心的评论之外,您的结构根本不是真正的结构。
  • 为什么它根本不是一个结构体?
  • 我认为结构混乱与您将页面布局 (HTML) 和页面行为 (jQuery) 组合到同一个术语“结构”这一事实有关。如果您使用匿名自执行函数,例如 $(function() {alert('do something after the page loading');}); ,您的初始化脚本不必出现在页面底部。您可以在 部分的顶部加载初始化脚本。如果您想尽量减少行为的代码重复,请将它们加载到页面顶部的库中。
  • 就是这样,我不想把脚本放在头上,这是一种基本的性能技术。脚本会阻止页面渲染,直到 JS 被下载并执行。如果你把它们放在最后页面首先呈现,然后下载脚本:developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5

标签: jquery asp.net-mvc asp.net-mvc-3 dhtml progressive-enhancement


【解决方案1】:

我已将@olivehour 响应标记为正确,因为它说明了问题的良好解决方案。

我最后做的,就是把jquery文件移到头部,只剩下jquery文件,其余的像“jquery-ui”,或者自定义的js文件还在底部。

原因是能够使用$(document).ready$(function(){}),因为在视图上使用它,代码在“onload”上执行,或者如果“onload”已经被提升,那么代码对我来说是完美的想要。

干杯。

【讨论】:

【解决方案2】:

如果我理解正确,这可能只是对您问题的部分回答。

关于您使用 &lt;input type="text" class="date" /&gt; 的示例,我们在使用 jQuery 非侵入式验证的部分表单视图中遇到了类似的问题。在浏览器中加载它们时,我们必须调用$.validator.unobtrusive.parse('a form selector'); 以便在下一次提交表单时应用验证规则。

如果您的目标是避免重复代码,您可以使用 jq unobtrusive 验证库中的模式使您的 js 操作不显眼。所以你最终会得到看起来更像这样的 HTML:

<input type="text" class="date" data-datepicker="true" />

然后您可以将初始化逻辑放在一个不显眼的解析方法中。

parse: function(selector) {
    $(selector).find(':input[data-datepicker=true]').each(function() {
        $(this).datepicker();
    }
};

}

这解决了您在一个地方重构代码的问题。你可以让它在页面第一次加载时自动启动,当你通过ajax加载新内容时,你可以通过调用myAppNamespace.unobtrusive.parse('selector for the partial view content');将规则应用于所有匹配的元素

更新

查看脚本文件夹中的 jquery.validate.unobtrusive.js 文件。它真的很聪明,如果你实际上没有扩展另一个 jquery 插件(如 validate),你的代码最终会变得更苗条。如果您正在寻找 HTML 和脚本的完全分离,使用 HTML5 不显眼的数据属性是一个很好的解决方案 imo。

【讨论】:

    猜你喜欢
    • 2015-10-29
    • 2010-10-30
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多