如何构建 Web 应用程序以使 AJAX 和 DHTML 更容易?

发布于 2024-12-18 19:43:55 字数 1862 浏览 4 评论 0原文

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

,使用正常的 Web 导航,页面完全以 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() 时会发生类似的问题,并且您动态添加新的 元素,除非重新执行 jQuery 语句,否则新元素没有日期选择器。

例如,考虑到在 #content 中我有一个

  1. 为了使jQuery datepicer 第一次工作,我必须 在 末尾调用 $('input.date').datepicker(), 在外部

  2. 如果页面下载了新的部分视图 elements,我必须将初始化调用放在ajax视图中

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

上周这让我抓狂,想知道是否有更好的方法来实现这一目标?更好的技术,还是其他整体方法?

您如何构建您的 Web 应用程序?

亲切的问候。

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

Given this structure for a 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>

Using normal web navigation, the page renders totally in HTML, and following the progressive enhancement approach, at the end I look for some specific ids or classes, and I give them dynamic behavior using javascript and specially jQuery. This enhancement code happens at the very end of the body, after the external scripts has been downloaded.

In #content, lot of jQuery AJAX interactions happens, some of them get other partial views from the server and insert them in the page, but then I have to look for those ids and classes again and attach javascript objects to this new elements.

It could be very cumbersome, since you don't want to reapply controllers, event handlers or whatever to objects that already have them.

So far, the only solution that I found is put in my partial views:

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

I think that a similar problem happens for example when you want $('input.date').datepicker() , and you add new <input type="text" class="date"/> elements dynamically, the new ones have no date picker unless you rexecute the jQuery sentence.

For example, considering that in #content I have an <input type="text" class="date"/>:

  1. In order to make the jQuery datepicer work the first time, I have to
    call $('input.date').datepicker() at the end of the <body>,
    after the external <script> declarations.

  2. If the page download partial views where are new <input type="text" class="date"/>
    elements, I have to put the initialization call in the view for ajax
    calls.

So I end with repeated code, something that I don't want specially in JS where I cannot refactor the code as easily as in C#.

This is something that is driving me nuts in the last week, wondering if there is a better way to accomplish this? A better technique, or other whole approach?

How do you structure your web applications?

Kind regards.

PS: Would be nice to have something like .live() or .delegate() but not only related with events, wouldn't it? Is not there any event that jQuery/browser raises everytime that something is added to the DOM?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空‖城人不在 2024-12-25 19:43:55

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

关于 的示例,我们在使用 jQuery 非侵入性验证的部分表单视图中遇到了类似的问题。当在浏览器中加载它们时,我们必须调用 $.validator.unobtrusive.parse('a form selecter'); 才能获取在下一次表单提交期间应用的验证规则。

如果您的目标是避免重复的代码,则可以使用 jq 不引人注目的验证库中的模式使 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 thepartial view content) 即可将规则应用于所有匹配元素');

更新

查看脚本文件夹中的 jquery.validate.unobtrusive.js 文件。它确实非常智能,如果您实际上没有扩展另一个 jquery 插件(例如 validate),您的代码最终会变得更精简。如果您正在寻找 HTML 和脚本的完全分离,那么使用 HTML5 不显眼的数据属性在我看来是一个很好的解决方案。

This may only be a partial answer to your question, if I understand it correctly.

Regarding your example with <input type="text" class="date" />, we experienced a similar issue with our partial form views that use jQuery unobtrusive validation. When loading them in the browser, we had to call $.validator.unobtrusive.parse('a form selector'); in order to get the validation rules to apply during the next form submission.

If your goal is to avoid repeated code, you could make your js actions unobtrusive, using a pattern like in the jq unobtrusive validation lib. So you would end up with HTML that looks more like this:

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

You can then put the initialization logic in an unobtrusive parse method.

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

}

This solves your problem of having one place to refactor the code. You can make it start up automatically when the page first loads, and when you load new content via ajax, you can apply the rule to all matching elements by just calling myAppNamespace.unobtrusive.parse('selector for the partial view content');

Update

Take a look at the jquery.validate.unobtrusive.js file in your scripts folder. It really is pretty smart, and if you're not actually extending another jquery plugin (like validate), your code would end up a lot slimmer. If you're looking for full separation of HTML and script, using the HTML5 unobtrusive data- attributes is a good solution imo.

热风软妹 2024-12-25 19:43:55

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

我最终所做的是将jquery文件移动到头部,只有jquery文件,其余的像“jquery-ui”或自定义js文件仍然在底部。

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

干杯。

I have marked the @olivehour response as correct, since it states a good solution for the problem.

What I have finally done, is move the jquery file to the head, and just the jquery file, the rest like "jquery-ui", or custom js files are still in the bottom.

The reason is being able to use $(document).ready or $(function(){}), since using that on the view, the code executes on "onload" or straightaway if the "onload" has been raised already, what is perfect for what I want.

Cheers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文