我有点困惑w.r.t.设计MVC时的结构依赖性 - 所以我们有一个模型,集合和视图(我还没有使用控制器,但问题也适用于它)。现在谁有人参考以OO术语发言。因此,集合是一个模型列表,因此我们可以将其视为从集合到模型的一对多依赖。在一些示例代码中,我有时会看到对“模型”对象中的视图的引用以及视图中模型的引用。有时是视图中的集合。
在模型中,我有时会看到一个this.view
,在视图中我会看到类似this.model.view
或this.model
的内容,因此会产生混淆以澄清:)
那么什么是“正确”的依赖关系(如果有“正确的方式”)或者每个人都可以依赖于每个人(不要认为这是正确的)即,理想情况下谁应该依赖于谁在Backbone的MVC对象设计中?当我看到这些截然不同的例子时,从结果的角度来看,知道他们应该如何在结构上相关,这有点令人困惑:)作为一个菜鸟什么是开始构建我的依赖关系的“正确”方式 - 一旦我上升了学习曲线我可能会自己弄清楚,但首先,应该怎么做呢?类似UML的图表将是额外的奖励;)
另一个问题: 有时我会在同一段代码中看到两个视图:例如:着名的todo.js http://documentcloud.github.com/backbone/docs/todos.html
现在虽然我理解需要多个视图,但令人困惑的是它们有何不同?我的意思是'el'和'tagName'之间的区别是什么?如果其中任何一个缺席,视图的表现会有何不同?我的意思是在上面的链接中,一个视图使用'tagName'而另一个'el',我不确定它们是如何关联的(如果有的话)。
我已经仔细阅读了文档,但正如我所说的那样,我仍然在学习,所以即使有了所有资源,我也可能根本无法理解它的一部分,可能需要人工干预:)
答案 0 :(得分:86)
由于Backbone.js不是这样的框架,因此没有任何单一的“正确”方法可以做任何事情。但是,实现中有一些提示可以帮助您理解。此外,您可以应用一些经过时间考验的通用代码组织实践。但我会先解释一下这些观点。
Backbone中的视图与特定的DOM元素绑定(这就是el
属性的用途)。
如果在初始化视图时它具有el
属性,则Backbone.js使其成为新视图实例的属性。否则,它会查找tagName
,id
和className
属性,创建相应的DOM对象,并将其分配给新视图实例的el
属性。 (在the source中对此进行了解释。)如果甚至没有tagName
,则默认情况下会创建<div>
元素。
因此,您可以猜测为什么TodoView
和AppView
使用不同的方法。 #todoapp
元素最初存在于HTML的页面上,因此AppView
可以使用它。但是当创建一个todo项目的视图时,它还没有DOM元素;所以开发人员在Backbone的类上定义了tagName
来自动创建一个列表项。 (在initialize()
方法中手动操作并不困难,但Backbone会为您节省一些时间。)
通常,视图属于以下两类之一:模型实例的视图和集合的视图。 Backbone不强制它,但它建议它可能是您想要的:如果您使用collection
或model
选项实例化视图,它们成为新创建的视图实例的属性,因此您可以通过view.collection
或view.model
访问它们。 (例如,如果您使用foo
选项实例化视图,则会将其放入view.options.foo
。)
这只是我的意见。
依赖性越低越好。
遵循MVC模式有很多优点。
请注意,Backbone.js术语与MVC的经典术语不匹配。这是正常的,MVC!=一组类,其定义有所不同。它更像是“你应该拥有的理想”(引自What is MVC and what are the advantages of it?)。
MVC | Backbone.js | What it does Controller | View (mostly) | Handles user interaction View | template rendered by a view | Displays the data Model | Model & Collection | Represents the data, handles data access
模型层通常不应依赖任何东西。在MVC中,model是您访问数据的地方。这与这些数据的呈现无关。
在Backbone中,模型可以是某个集合的一部分,但这不是一个重度依赖(AFAIK,它只是有助于自动找出与此模型对应的API端点的URL。)
在Backbone中,集合可能已分配相应的模型类,但这也不是必需的。
在Backbone中,路由器通常依赖于更高级别的视图(如整个页面或页面部分的视图),以响应应用程序状态的变化来呈现它们。反过来,这些视图依赖于一些较低级别的视图,例如小部件/页面部分。这些视图可能取决于集合和其他更低级别的视图。反过来,这些可能取决于特定的模型实例。
作为一个例子(箭头表示“依赖于”关系类型):
+-------------+ +---------------+ +------------+ State |MainRouter | Data: |ItemCollection | |ItemModel | Control: |-------------| |---------------| |------------| | | |/api/items +-->|/api/items/*| | | | | | | | | | | | | +---+-+-------+ +---------------+ +------------+ | +----------------+ ^ ^ v v | | +-------------+ +-------------+ | | Page-level |AboutView | |AppView | | | views: |-------------| |-------------| | | | section | | section | | | | role="main" | | role="main" | | | +--+-+--------+ +--+-+-+------+ | | | +---------------|-|-|----+ | | | +----------+ | +----|---------+ | | v v v v v | | +--------------+ +--------------+ +---+-----------+ | Widget |SidebarView | |HeaderView | |ItemListView | | views: |--------------| |--------------| |---------------| | | aside | | header | | ul | | | | | | | | | | | | | | | | +--------------+ +--------------+ +-----------+---+ | | | v | +--------+---+ |ItemAsLiView| |------------| | li | | | +------------+
请注意,您可以设置多个路由器,在这种情况下,事情可能会有所不同。
在Todos示例中,开发人员决定Todo
模型实例应该依赖于相应的TodoView实例。实例化TodoView
时,它会在相应的模型实例上创建一个属性view
并将其自身分配给它。因此some_todo_model.view
可以访问它。但是,应该注意model.view
仅在Todo
模型的clear()
方法中使用,以便在清除模型时删除视图实例。
我认为 特定的依赖关系不是必需的。但是,对于这么小的应用程序,它可能没问题。
我找不到在视图中访问this.model.view
的任何示例,因此我无法对此发表评论。