了解Backbone.js中MVC的内部结构依赖关系
我在deviseMVC时对结构依赖有点困惑 – 所以我们有一个Model,Collection和View(我现在还没有使用控制器,但这个问题也适用于它)。 现在有谁可以用OO来说话。 所以集合是一个模型列表,所以我们可以把它看作是从集合到模型的一对多的依赖关系。 在一些示例代码中,我有时会看到对“模型”对象中视图的一些引用以及视图中模型的引用。 有时在视图中的集合。
在模型中,我有时会看到一个this.view
并在视图中看到像this.model.view
或this.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将它作为新视图实例的一个属性。 否则,它会查找tagName
, id
和className
属性,创build相应的DOM对象,并将其分配给新视图实例的el
属性。 (这在源代码中有解释)如果甚至没有tagName
,那么默认情况下会创build<div>
元素。
所以,你可以猜测为什么TodoView
和AppView
使用不同的方法。 #todoapp
元素最初存在于HTML中的页面上,所以AppView
可以使用它。 但是,当创build一个todo项目的视图时,还没有DOM元素。 所以开发者在Backbone类上定义了tagName
来自动创build一个列表项。 (在initialize()
方法中手工操作并不难,但Backbone会为您节省一些时间。)
通常,视图分为两类:模型实例视图和集合视图。 骨干不强制它,但它表明它可能是你想要的:如果你使用collection
或model
选项实例化视图,它们成为新创build的视图实例的属性,所以你可以通过view.collection
或view.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,我认为这是一个很好的信息来源。