Tho*_*mas 26 javascript model-view-controller view backbone.js
我正在构建我的第一个Backbone.js应用程序,我很担心我应该给予或隐藏我的视图多少责任.
在我的示例中,我正在构建一个Rich UI表(类似于YUI的datagrid),它是从Collection动态生成的.在我的应用程序中,我称之为"AppTable".在我对MVC的理解中,我会想到会有某种AppTable控制器找到正确的Collection,抓取一个"哑"视图并传递给View所需呈现的任何信息.在这个Senario中,View只会提供提供给它的数据并相应地修改DOM,甚至可以填充模板或附加事件监听器.
Backbone似乎消除了控制器在View和Collection之间进行调解的想法.相反,View通过对Collection的引用进行初始化,并且View负责更新自身.
我是否正确理解了这种架构?
假设我这样做,我的问题就变成了,当我的View需要做的越来越多时会发生什么?例如,我想要列排序,拖放行,分页,搜索,表控制链接(如新建,复制,删除行等)等等.如果我们坚持使用View直接连接到Collection的"智能"View范例,上面的函数是否会附加到View对象?
通过这个思考,我可以看到View从一个简单的表包装器变成了一个非常混乱的野兽,附带了很多功能.那么,View在这种情况下真的是一个控制器吗?
Jos*_*zel 22
您对架构的理解是正确的.Backbone不承认传统MVC意义上的"控制器"的概念.(实际上,Backbone实际上有一个名为a的对象Controller,但它已被重命名Router以更准确地描述它的作用.)
您列出的功能(拖放,删除行,排序等)都属于视图.视图描述您看到的内容并响应用户输入.任何涉及事件(点击,按键,提交等)的内容都会进入视图.但是你的观点永远不应该实际操纵数据; 这应该由它完成model.您认为视图就像控制器一样是正确的,因为它打包数据并将其发送到模型,然后模型将适当地验证/设置/保存.一旦发生这些操作,视图将重新呈现为表示模型内数据的新版本.
需要注意的一点是:您的观点不应过于依赖DOM.Backbone惯例是拥有一个与视图绑定的顶级DOM元素(例如,一个表单或一个div),然后只处理它的子元素.这是合适的; 一般情况下,视图中的"从此div中删除此链接"之类的内容不是.如果您发现您的视图变得笨拙,您很可能需要将其分解为子视图,每个视图都将其各自的行为作为整体的组成部分.
Mau*_*ord 10
我对此的想法更新如下: 我认为Josh给出了一个很好的答案,但是,根据我的经验,构建一些Backbone应用程序,即使是中等复杂度的应用程序也需要一个单独的控制器类.
澄清我对控制器的意思:模型(或路由器)与创建和实例化新视图类并在旧视图类上杀死(和取消注册事件)的视图之间的功能.此功能可能是很多看法(所以视图和控制器之间的直接的一对一关系,可能也没必要),但有时一个需要在模型或其他附加额外的值,以使其通过.
现在,我只有一个带有一些if语句的控制器,用于为我构建的大多数应用程序添加一些独特的数据到某些视图但是我正在设置一个架构,它将检查是否存在一个独特的控制器那个视图,否则它会回到标准控制器.没什么特别的,但应该做的工作.
更新:在构建Backbone应用程序六个月后,我意识到路由器可以像视图一样拆分和扩展.(杜?)
马上就知道我知道我的所有观点都需要的功能基础视图.同样,我会为每个部分制作基本视图,例如"profile"页面或"收件箱"页面,我知道这些页面都将使用相同的功能.对于我来说,这对路由器来说并不是那么清楚,但之前的名称"Controller"暗示了这一点.
大多数人(就像我在Web上看到的每个Backbone示例一样)只使用一个单片路由器实例来处理所有路由,但实际上你可以将1到1奇偶校验的路由器用于视图,或者在我的例子中,用于检查用户身份验证等的基本路由器,然后为每个主要部分检查一个.这样,如果您需要在页面加载时将某些模型或集合传递给路由器,则不需要将代码添加到一个单片路由器,而是为该视图拉出唯一的路由器.我发现这比创建一个单独的控制器类要好.基础路由器可以负责最后实例化的视图等,因此您可以在实例化新视图之前终止最后一个视图.
TLDR:使用多个路由器作为控制器.我相信这是他们的意思,而且运作良好.
在尝试绘制单页应用程序时,我一直在努力解决相同的语义问题.最后,我认为Backbone使用了错误的名称.
当您在浏览器中查看Backbone应用程序时,View实际上根本不是视图,其el成员是视图.Backbone.View是一个视图控制器,或者更准确地说,是一个演示者.
一些支持证据:
你永远不会看到一个Backbone.View在屏幕上,它始终el还是$el被应用到DOM
a Backbone.View不接收用户输入,DOM元素接收输入,并通过events"视图" 的散列委托事件
一个BackBone.View管理模型或集合的变化和转换这些变化到哑视图(DOM)的元素,然后将它们应用于实际视图,例如this.$el.append('<p>Cats!')
我认为Backbone.Presenter这是一个更好的名字,但我也可以看到有一个前者的历史问题Backbone.Controller和重新命名的工作量介绍.
我为我的最新项目确定了以下结构:
一个app控制器,从扩展Backbone.View,绑定到body元素
几个模型集合,用于缓存从服务器检索的数据
a Backbone.Router将路由更改转换为Backbone事件并在其自身上触发它们
许多app控制器方法,用于处理app控制器侦听的路由器事件
应用程序控制器方法准备任何所需的模型,然后启动演示者(扩展Backbone.View)并将其附加到body元素
所有这些部件都由app控制器启动和拥有.演示者不知道他们在页面上的原因或位置,只关心他们自己的DOM元素以及他们从中获得的更改this.model.
看看这部分骨干文档
http://documentcloud.github.com/backbone/#FAQ-tim-toady
模型和视图之间的引用可以通过多种方式处理.有些人喜欢直接指针,其中视图与模型(model.view和view.model)1:1对应.其他人更喜欢拥有中间"控制器"对象,这些对象将视图的创建和组织编排成层次结构.其他人仍然喜欢这种方法,并且总是触发事件而不是直接调用方法.所有这些风格都很好用.
因此,骨干不会为您做出决定.
我有一个非常相似的用例(带有分页,排序,实时过滤的表格,带有客户端验证的表格,主要细节关系等)
在我的情况下,我首先开始使用路由器,就像控制器一样,很快我的代码就变得有些混乱了.
所以我完全删除了路由器(我稍后会将它们添加回去,但只是作为一个补充)并创建了我自己的控制器(实际上它是一个演示者).它只是一个javascript类,Backbone.extend支持处理继承.
我们的想法是视图接收显示自身所需的所有数据(模型,集合和应该在其中解析的el),在dom事件上设置监听器,然后执行控制器方法.它永远不会直接修改数据,也不会与其他视图交互,它会告诉控制器执行此操作.
视图可以包含子视图,在这种情况下,子视图仅与父视图交互,或直接与控制器交互.
到目前为止它似乎工作,但无论如何事情并不像我预期的那样简单......
我希望在接下来的几天内发布它.
| 归档时间: |
|
| 查看次数: |
5893 次 |
| 最近记录: |