JavaScript 中的代码组织:MVC?自渲染组件?
Posted
技术标签:
【中文标题】JavaScript 中的代码组织:MVC?自渲染组件?【英文标题】:Code organization in JavaScript: MVC? Self-rendering components? 【发布时间】:2011-07-17 23:58:28 【问题描述】:我正在构建一个非常依赖 JS 的 Web 应用程序。我说这是 JS-heavy,因为绝大多数工作都是在客户端完成的(尽管有一些使用 AJAX 和 XMPP 来回同步到服务器)。
这是我第一次在纯 JS 中(使用 jQuery)构建这种规模的东西,所以我开始使用 MVC 以模仿 Rails 的方式组织我的代码。例如,如果用户单击一个按钮,则会在 Controller 对象中调用一个方法,该方法从模型中提取一些数据,然后将数据传递给视图函数。我几乎对所有事情都这样做,甚至是像显示一个小弹出窗口这样的琐碎操作。
几个月后,我觉得我没有充分利用这门语言。我真的应该像网页一样呈现我的视图吗?
将视图分解为组件似乎更有意义,这些组件将是 javascript 对象/函数的实例。例如,而不是...
var itemListhtml = '<ul id="item-list"><li>item1</li><li>item2</li></ul>';
jQuery('#container').html(itemListHTML);
...我本来可以...
components.itemList.render();
所以这里只有一个名为itemList
的组件。由于所有数据都存储在客户端上,因此这些组件可以立即访问创建和管理自身所需的所有数据。我想我仍然会使用 MVC,但不需要负责整个视图的控制器操作。如果我想刷新 UI 的一部分,我只需调用 whateverComponentControlsThatArea.redraw()
并重新呈现自己。
我确信以前有人这样做过。这种代码组织方式有名称吗?有关如何实施它的任何指南或最佳实践?
【问题讨论】:
你见过backbone.js吗? documentcloud.github.com/backbone 现在正在阅读,目前看起来很棒 很难说出你真正的问题是什么 【参考方案1】:现在有许多可用的 javascript MVC 框架例如JavaScriptMVC、PureMVC、Sammy.js。 通常通过某种模板引擎处理视图或子视图的呈现。 JavaScriptMVC 有一个模块EJS,它以ERB 为模型,我发现它非常有用。模板可以编译成函数以加快生产速度。 还有其他模板解决方案,例如 John Resig's Micro-Templating 和 many more
如果还不算太晚,我建议您使用其中一种框架。我已经在几个项目中使用了 JavaScriptMVC,并且可以推荐它(文档需要一些时间来适应)
【讨论】:
【参考方案2】:您真的应该研究 jquery.tmpl (http://api.jquery.com/jquery.tmpl/) 以创建适合构建视图渲染的快速 javascript 模板。
【讨论】:
【参考方案3】:聚会有点晚了,但我这里有 0.02 美元,我不知道该怎么处理...
暂时忘记(典型的)Web-MVC(即:RailsMVC 等):
考虑到 JavaScript 可以都驻留在同一个地方,并且您不必担心确定路由和类实例化(除非您真的想这样做)。
理想情况下,从软件的角度来看,您希望 MVC 做的是将用户所做的事情与构成内容的内容(基于动作)和构成视图的内容(基于动作)分开)。
没有什么说你不能有多个视图,甚至你不能有一个包含多个视图的视图(可能使用模板,或者是功能生成的,并附加到一个 DOM 节点 - 要么是有效)。
在一个简单的伪示例中,而不是具有如下所示的流程:
动作加载控制器 -> 控制器加载模型 -> 控制器查询模型 -> 模型回答控制器 -> 控制器加载视图 -> 控制器将数据馈送到视图 -> 视图将页面发送到控制器 -> 控制器输出页面
为什么不这样:
Controller 监听 Action (addEventListener) -> Controller 将 Action 变成 State-Logic -> Controller 通知 Model (observer) OR Model Polls Controller -> Model 根据逻辑改变状态,并收集/排序所有数据 -> Model Notifies View (observer) OR View Polls Model -> View Changes State based on Logic -> View Renders all Components, based on Data + ViewState (innerHTML OR documentFragment)。
它看起来有点长,但实际上,一切都很好而且分开。 使用视图(或视图管理器,或者你想怎么想)来规定页面上的窗口、每个窗口的组成方式、数据的去向、每篇文章的内部、每个窗口中...
...现在你有一个 MVC 模式,但你也有能力说:
View["mainpage"] =
data : tweets : [id:......]/* et cetera - pushed by Model, not Controller */ ,
layout : [ "Header", "Carousel", "Articles", "TwitterFeed", "RSSFeed", "Footer" ],
// if your system is this clean, you could even prototype the content-builders
// rather than defining them in each ViewState - you'd just need layout, then
buildPage : function ()
var page = document.createDocumentFragment();
for (/* everything in this.layout */)
View.build[this.layout[i]](this.data, page);
document.body.appendChild(page);
,
cleanUp : function () /* fancy or simple DOM cleaning for state-change */ ,
// grabs SubView by expected handle (id="tweetfeed" or whatever) and replaces it
// observer functionality, for views to automatically update as data changes
updateView : function (view, newData) ... ,
addData : function (data) this.data = data; , // for Observer
/* Observer - if you want to run the WHOLE site with AJAX from index.html
* clean up old (ex:"main") page and build and/or transition new (ex:"media") page
* could be unique for each page, for custom transitions, or just prototype it */
changeState : function (newState, newData)
View["mainpage"].cleanUp();
View[newState].addData( newData );
View[newState].buildPage();
现在您已经定义了整个主页。 当然,不仅要维护主页的定义,还要维护每个页面/部分的定义,这将是一项额外的工作。 ...然后,您需要创建将创建每个子视图的功能——但基于组件的设计正是您所要求的。 本质上,对于每个小部件,它都有自己的构建逻辑。 这就是视图的作用——它们要么有一个可以重复使用的单独模板,要么有一个每次都以相同方式工作的函数。
原子视图是您处理构建 1 个项目(1 个推文、1 个帖子、1 个商店项目)并为此构建视图的函数。 让 Single_Tweet 视图连续 20 次向页面发布一条推文对于 JS 性能来说是一个坏的想法。
但是,让 Single_Tweet 视图将推文按顺序推送到 Twitter_Feed 视图放在网站上的 Tweets 数组中是正常的。
如果你的页面是视图,由视图的小部件组成,由视图的原子单元组成,那就更好了。 当所有这些都发生在 DOM 之外(所以是 innerHTML 或 documentFragment)。
最好的框架是您以这种方式定义页面的框架,但您也可以随时根据模型的数据推送更新单个小部件。
这就是 AJAX 的美妙之处——老式的 MVC 可以发生,没有一个无所不知的控制器。
控制器只保存一个按键列表、鼠标坐标、点击按钮的意图...... 它告诉模型发生了什么事。 模型会处理所有与状态/数据/数据操作(排序)相关的事情,并将新状态或数据提供给视图,视图会按照您指定的顺序将其全部接收并放入 HTML。
就是这样。
【讨论】:
以上是关于JavaScript 中的代码组织:MVC?自渲染组件?的主要内容,如果未能解决你的问题,请参考以下文章