了解Backbone.js中MVC的内部结构依赖关系

我在deviseMVC时对结构依赖有点困惑 – 所以我们有一个Model,Collection和View(我现在还没有使用控制器,但这个问题也适用于它)。 现在有谁可以用OO来说话。 所以集合是一个模型列表,所以我们可以把它看作是从集合到模型的一对多的依赖关系。 在一些示例代码中,我有时会看到对“模型”对象中视图的一些引用以及视图中模型的引用。 有时在视图中的集合。

在模型中,我有时会看到一个this.view并在视图中看到像this.model.viewthis.model ,因此混淆澄清:)

那么什么是“正确”的依赖关系(如果存在“一个正确的方式”),或者每个人都可以依赖于每个人(不要认为这是正确的),也就是说,理想上谁应该依赖于Backbone的MVC对象的devise? 当我看到这样不同的例子时,我们知道它们在结构上应该如何相互混淆呢?从noob的angular度来看:)作为一个noob什么是开始构build我的依赖关系的“正确”方式 – 一旦我起来学习曲线我可能会自己想出来,但首先,应该怎么做呢? 一个类似UML的图将是一个额外的奖励;)

另一个问题:有时我会在同一段代码中看到两个视图:例如:着名的todo.js http://documentcloud.github.com/backbone/docs/todos.html

现在,尽pipe我明白了多种观点的需要,但是混淆的是他们有什么不同呢? 我的意思是“el”和“tagName”之间的区别是什么,如果其中一个不存在,视图的行为有什么不同? 我的意思是在上面的链接中,一个视图使用“tagName”和另一个“el”,我不确定它们是如何关联的(如果有的话)。

我已经仔细阅读了文档,但正如我所说的,我还在学习,所以即使所有的资源已经到位,我也可能不清楚其中的部分内容,可能需要人为干预:)

由于Backbone.js不是一个框架,所以没有一个“正确的”方法可以做任何事情。 但是,在实现中有一些提示可以帮助你理解。 另外,还有一些可以应用的经过时间考验的通用代码组织实践。 但我会先解释一下意见。

查看

Backbone中的视图与特定的DOM元素绑定(这是el属性的用途)。

如果初始化视图的时候,它有一个el属性,那么Backbone.js将它作为新视图实例的一个属性。 否则,它会查找tagNameidclassName属性,创build相应的DOM对象,并将其分配给新视图实例的el属性。 (这在源代码中有解释)如果甚至没有tagName ,那么默认情况下会创build<div>元素。

所以,你可以猜测为什么TodoViewAppView使用不同的方法。 #todoapp元素最初存在于HTML中的页面上,所以AppView可以使用它。 但是,当创build一个todo项目的视图时,还没有DOM元素。 所以开发者在Backbone类上定义了tagName来自动创build一个列表项。 (在initialize()方法中手工操作并不难,但Backbone会为您节省一些时间。)

通常,视图分为两类:模型实例视图和集合视图。 骨干不强制它,但它表明它可能是你想要的:如果你使用collectionmodel选项实例化视图,它们成为新创build的视图实例的属性,所以你可以通过view.collectionview.model来访问它们view.model 。 (例如,如果你用foo选项实例化视图,它将被放入view.options.foo 。)

依赖

好的做法

这只是我的看法。

  • 依赖性越less越好。

  • 遵循MVC模式有很多优点。

    请注意,Backbone.js术语不符合MVC的经典术语。 这很正常,MVC!=一组类,它的定义有所不同。 这更像是“你应该拥有的理想”(引用MVC是什么,它的优点是什么? )。

 MVC |  Backbone.js | 它能做什么
控制器| 查看(大部分)| 处理用户交互
查看| 由视图呈现的模板| 显示数据
模型| 模型和集合| 代表数据,处理数据访问
  • 模型层通常不应该依赖于任何东西。 在MVC中,模型是您访问数据的地方。 这与这个数据的expression无关。

    在Backbone中,模型可以是某个集合的一部分,但这不是一个沉重的依赖(AFAIK,它只是帮助自动找出与这个模型相对应的API端点的URL)。

  • 在Backbone中,一个集合可能有一个对应的模型类被分配,但这也不是必需的。

  • 在Backbone中,路由器通常依赖于更高级别的视图(如整个页面或页面的部分视图),以响应应用程序状态的更改来呈现它们。 这些视图依次取决于一些较低级别的视图,如小部件/页面部分。 这些视图可以依赖于集合和其他甚至更低层次的视图。 这些又可以依赖于特定的模型实例。

举一个例子(箭头表示“取决于”关系types):

            + ------------- + + --------------- + + ------------ +
州| MainRouter | 数据:| ItemCollection |  | ItemModel |
控制:| ------------- |  | --------------- |  | ------------ |
            |  |  | / api / items +  - > | / api / items / * |
            |  |  |  |  |  |
            |  |  |  |  |  |
            + --- +  -  + ------- + + --------------- + + ------------ +
                |  + ---------------- + ^ ^
                vv |  |
            + ------------- + + ------------- + |  |
页面级|关于查看|  | AppView |  |  |
 views:| ------------- |  | ------------- |  |  |
            | 部分|  | 部分|  |  |
            | angular色=“主”|  | angular色=“主”|  |  |
            +  -  +  -  + -------- + +  -  +  -  +  -  + ------ + |  |
               |  + --------------- |  -  |  -  | ---- + |  |
               |  + ---------- + |  + ---- | --------- + |  |
               vvvvv |  |
            + -------------- + + -------------- + + --- + ----------- + |
小工具|侧栏查看|  | HeaderView |  | ItemListView |  |
 views:| -------------- |  | -------------- |  | --------------- |  |
            | 在...旁边  |  header |  |  ul |  |
            |  |  |  |  |  |  |
            |  |  |  |  |  |  |
            + -------------- + + -------------- + + ----------- + --- + |
                                                              |  |
                                                              v |
                                                            + -------- + --- +
                                                            | ItemAsLiView |
                                                            | ------------ |
                                                            |  li |
                                                            |  |
                                                            + ------------ +

请注意,您可以设置多个路由器,在这种情况下,情况可能会有所不同。

todos.js

在Todos的例子中,开发者决定Todo模型实例应该依赖于相应的TodoView实例。 当TodoView被实例化时,它会在相应的模型实例上创build一个属性view并将其自身分配给它。 这样可以通过some_todo_model.view来访问。 但是,应该注意的是, model.view仅在Todo模型的clear()方法中使用一次,以在清除模型时移除视图实例。

我认为这种特殊的依赖是没有必要的。 但是,对于这样一个小的应用程序,可能没关系。

我找不到在视图中访问this.model.view任何示例,所以我不能对此进行评论。

也可以看看

  • Julien Guimont的答案几乎都是关于Backbone.js,我认为这是一个很好的信息来源。