javaScript 客户端代码的替代“架构”方法?

Posted

技术标签:

【中文标题】javaScript 客户端代码的替代“架构”方法?【英文标题】:Alternative "architectural" approaches to javaScript client code? 【发布时间】:2010-09-07 03:32:42 【问题描述】:

您的 javascript 代码是如何组织的?它是否遵循 MVC 之类的模式或其他模式?

我一直在从事一个业余项目,并且越深入,我的网页就越能变成一个功能齐全的应用程序。现在,我坚持使用jQuery,但是,页面上的逻辑正在增长到需要某种组织,或者我敢说,“架构”是必要的。我的第一种方法是“MVC-ish”:

“模型”是一个 JSON 树,可通过帮助程序进行扩展 视图是 DOM 加上调整它的类 控制器是我连接事件处理和启动视图或模型操作的对象

不过,我对其他人如何构建更强大的 JavaScript 应用程序非常感兴趣。我对 GWT 或其他面向服务器的方法不感兴趣......只是对“javaScript + ”的方法

注意:之前我说过 javaScript“不是真正的 OO,不是真正的功能”。我想,这让每个人都分心了。这么说吧,因为 javaScript 在很多方面都是独一无二的,而且我来自强类型背景,我不想强​​制使用我知道的范式,但它们是用非常不同的语言开发的。

【问题讨论】:

【参考方案1】:

JavaScriptMVC 是组织和开发大型 JS 应用程序的绝佳选择。

架构设计经过深思熟虑。您将使用 JavaScript 做 4 件事:

    响应事件 请求数据/操作服务 (Ajax) 将特定于域的信息添加到 ajax 响应中。 更新 DOM

JMVC 将这些拆分为模型、视图、控制器模式。

首先,也可能是最重要的优势是控制器。控制器使用事件委托,因此您无需附加事件,只需为您的页面创建规则。他们还使用控制器的名称来限制控制器的工作范围。这使您的代码具有确定性,这意味着如果您在“#todos”元素中看到事件发生,您就知​​道必须有一个 todos 控制器。

$.Controller.extend('TodosController',
   'click' : function(el, ev) ... ,
   '.delete mouseover': function(el, ev) ...
   '.drag draginit' : function(el, ev, drag) ...
)

接下来是模型。 JMVC 提供了一个强大的类和基本模型,让您可以快速组织 Ajax 功能(#2)并使用特定于域的功能包装数据(#3)。完成后,您可以使用控制器中的模型,例如:

Todo.findAll(after: new Date(), myCallbackFunction);

最后,一旦您的待办事项返回,您必须显示它们(#4)。这是您使用 JMVC 视图的地方。

'.show click' : function(el, ev) 
   Todo.findAll(after: new Date(), this.callback('list'));
,
list : function(todos)
   $('#todos').html( this.view(todos));

在'views/todos/list.ejs'中

<% for(var i =0; i < this.length; i++) %>
   <label><%= this[i].description %></label>
<%%>

JMVC 提供的不仅仅是架构。它可以帮助您在开发周期的任何阶段:

代码生成器 集成浏览器、Selenium 和 Rhino 测试 文档 脚本压缩 错误报告

【讨论】:

【参考方案2】:

只是一个快速的澄清。

编写非面向服务器的 GWT 应用程序是完全可行的。我假设从面向服务器的角度来看,您的意思是需要基于 Java 的后端的 GWT RPC。

我只在客户端编写了非常“MVC 风格”的 GWT 应用程序。

模型是一个对象图。尽管您在 Java 中编写代码,但在运行时对象是在 javascript 中,在客户端或服务器端都不需要任何 JVM。 GWT 还支持具有完整解析和操作支持的 JSON。您可以轻松连接到 JSON Web 服务,请参阅 2 以获取 JSON 混搭示例。 View 由标准 GWT 小部件(加上我们自己的一些复合小部件)组成 控制器层通过观察者模式巧妙地与视图分离。

如果您的“强类型”背景使用 Java 或类似语言,我认为您应该认真考虑将 GWT 用于大型项目。对于小型项目,我通常更喜欢 jQuery。即将推出的与 GWT 1.5 配合使用的 GWTQuery 可能会改变这一点,但由于 jQuery 的插件很多,因此在不久的将来不会改变。

【讨论】:

【参考方案3】:

Tristan,您会发现,当您尝试将 JavaScript 构建为 MVC 应用程序时,它往往会在一个方面出现不足——模型。最难处理的领域是模型,因为数据不会在整个应用程序中持续存在,而且从本质上讲,模型在客户端的变化似乎相当一致。您可以标准化从服务器传递和接收数据的方式,但此时模型并不真正属于 JavaScript —— 它属于您的服务器端应用程序。

不久前我确实看到有人尝试创建了一个用 JavaScript 建模数据的框架,就像 SQLite 属于应用程序的方式一样。就像 Model.select("Product") 和 Model.update("Product", "Some data...")。它基本上是一个对象表示法,它包含一堆数据来管理当前页面的状态。但是,刷新的那一刻,所有数据都会丢失。我可能不了解语法,但你明白了。

如果您使用的是 jQuery,那么 Ben 的方法确实是最好的。使用您的函数和属性扩展 jQuery 对象,然后划分您的“控制器”。我通常通过将它们放入单独的源文件中并逐节加载它们来做到这一点。例如,如果它是一个电子商务网站,我可能有一个 JS 文件,其中包含处理结帐流程功能的控制器。这往往会使事情变得轻巧且易于管理。

【讨论】:

【参考方案4】:

感谢大家的回答。过了一段时间,我想发布一下我目前学到的东西。

到目前为止,我发现使用 Ext 之类的方法和 JQuery UI、Scriptaculous、MochiKit 等其他方法存在很大差异。

使用 Ext,HTML 只是一个占位符 - UI 在这里。从那时起,一切都用 JavaScript 描述了。 DOM 交互在另一个(可能更强大的)API 层下被最小化。

对于其他工具包,我发现自己从做一些 HTML 设计开始,然后用时髦的效果直接扩展 DOM,或者只是在这里替换表单输入,在那里添加。

主要区别开始出现,因为我需要处理事件处理等。由于模块需要相互“对话”,我发现自己需要远离 DOM,将其抽象为碎片。

我注意到其中许多库还包含一些有趣的模块化技术。 Ext 网站上提供了非常清晰的描述,其中包括a fancy way to "protect" your code with modules。

我没有完全评估过的新玩家是Sproutcore。看起来像是 Ext in 方法,其中 DOM 是隐藏的,您最想处理项目的 API。

【讨论】:

【参考方案5】:

MochiKit 很棒——可以说是我的初恋,就 js 库而言。但我发现,虽然 MochiKit 的语法非常富有表现力,但它对我的感觉却不如 Prototype/Scriptaculous 或 jQuery 对我来说那么舒服。

我想如果你知道或喜欢 python,那么 MochiKit 对你来说是一个很好的工具。

【讨论】:

【参考方案6】:

不是 100% 确定您在这里的意思,但我会说,在过去 6 年使用 ASP.NET 之后,一旦基本页面呈现由服务器完成,我的网页现在主要由 JavaScript 驱动。我对所有事情都使用 JSON(已经使用了大约 3 年),并使用 MochiKit 来满足我的客户端需求。

顺便说一句,JavaScript OO,但由于它使用原型继承,人们不会以这种方式相信它。我还认为它也是功能性的,这完全取决于你如何编写它。如果你真的对函数式编程风格感兴趣,请查看MochiKit——你可能会喜欢它;它在很大程度上倾向于 JavaScript 的函数式编程方面。

【讨论】:

【参考方案7】:

..但是 Javascript 有很多方面面向对象的。

考虑一下:

var Vehicle = jQuery.Class.create( 
   init: function(name)  this.name = name;  
);

var Car = Vehicle.extend( 
   fillGas: function() 
      this.gas = 100; 
    
);

我已经使用这种技术创建了具有自己状态的页面级 javascript 类,这有助于保持它的包含(而且我经常确定可以重用并放入其他类的区域)。

当您的组件/服务器控件有自己的脚本要执行时,这也特别有用,但是当您可能在同一页面上有多个实例时。这使状态保持独立。

【讨论】:

以上是关于javaScript 客户端代码的替代“架构”方法?的主要内容,如果未能解决你的问题,请参考以下文章

这种 for 循环迭代的替代方法是如何工作的? (Javascript)[重复]

JavaScript - 使用扩展操作或替代方法向对象添加额外的键值

什么是加载剥离javascript并将其放入数组以供以后使用的替代方法

SOA 与 MVC - 何时使用

Browserify有替代品吗? [关闭]

JavaScript 中拼接函数的替代方法