【问题标题】:Understanding the internal structural dependencies of MVC in Backbone.js了解Backbone.js中MVC的内部结构依赖
【发布时间】:2011-10-03 08:02:24
【问题描述】:

我有点困惑w.r.t。设计 MVC 时的结构依赖关系 - 所以我们有一个模型、集合和视图(我还没有使用控制器,但这个问题也适用于它)。现在谁有谁的参考 OO 术语。所以集合是一个模型列表,所以我们可以把它看作是从集合到模型的一对多依赖。在一些示例代码中,我有时会在“模型”对象中看到对视图的一些引用以及对视图中模型的引用。有时是视图中的集合。

在模型中,我有时会看到 this.view,而在视图中,我会看到 this.model.viewthis.model 之类的东西,因此需要澄清:)

那么什么是“正确”的依赖集(如果存在“一种”正确的方式)或者每个人都可以依赖每个人(不要认为这是正确的)即,理想情况下谁应该依赖于谁在 Backbone 的 MVC 对象设计中?当我看到这些不同的例子时,知道它们应该如何在结构上相关,这有点令人困惑——从菜鸟的角度来看:) 作为菜鸟,什么是开始构建我的依赖关系的“正确”方式——一旦我开始了学习曲线我可能会自己弄清楚,但首先,应该怎么做呢?类似 UML 的图表将是一个额外的好处;)

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

现在虽然我了解多个视图的需要,但令人困惑的是它们有何不同?我的意思是“el”和“tagName”之间有什么区别,如果其中任何一个不存在,视图的行为会有什么不同?我的意思是在上面的链接中,一个视图使用“tagName”,另一个使用“el”,我不确定它们之间的关系(如果有的话)。

我已经深入阅读了文档,但正如我所说,我仍在学习,所以即使有所有资源,我也可能无法清楚地理解其中的部分内容,并且可能需要一些人工干预 :)

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    由于 Backbone.js 本身不是一个框架,因此没有单一的“正确”方法可以做任何事情。但是,实现中有一些提示可以帮助您理解这个想法。此外,您还可以应用一些经过时间考验的通用代码组织实践。但我会先解释一下观点。

    观看次数

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

    如果在初始化视图时,它有一个el 属性,那么 Backbone.js 会将它作为新视图实例的属性。否则,它会查找tagNameidclassName 属性,创建相应的DOM 对象,并将其分配给新视图实例的el 属性。 (在the source中有解释。)如果连tagName都没有,则默认创建<div>元素。

    所以,您可以猜到为什么TodoViewAppView 使用不同的方法。 #todoapp 元素最初存在于 HTML 的页面中,因此 AppView 可以直接使用它。但是当一个待办事项的视图被创建时,它还没有 DOM 元素;因此开发人员在类上定义了tagName,以便 Backbone 自动创建列表项。 (在initialize() 方法中手动操作并不难,但Backbone 会为您节省一些时间。)

    通常,视图属于以下两类之一:模型实例视图和集合视图。 Backbone 不会强制它,但它建议这可能是您想要的:如果您使用collectionmodel 选项实例化视图,它们将成为新创建的视图实例,因此您可以通过view.collectionview.model 访问它们。 (例如,如果您使用foo 选项实例化视图,它将被放入view.options.foo。)

    依赖关系

    良好做法

    这只是我的意见。

    • 依赖越少越好。

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

      请注意,Backbone.js 术语与 MVC 的经典术语不匹配。这很正常,MVC != 一组类,其定义略有不同。它更像是“您应该在脑海中拥有的理想”(引自What is MVC and what are the advantages of it?)。

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

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

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

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

    例如(箭头表示“取决于”关系类型):

    +-------------+ +----------------+ +------------+ 状态 |MainRouter |数据: |ItemCollection | |产品型号 | 控制:|--------------| |---------------| |------------| | | |/api/items +-->|/api/items/*| | | | | | | | | | | | | +---+-+-------+ +----------------+ +------------+ | +----------------+ ^ ^ v v | | +-------------+ +-------------+ | | 页面级 |AboutView | |应用查看 | | | 浏览量:|-------------| |--------------| | | |部分 | |部分 | | | |角色="主要" | |角色="主要" | | | +--+-+--------+ +--+-+-+------+ | | | +---------------|-|-|----+ | | | +----------+ | +----|---------+ | | v v v v v | | +--------------+ +--------------+ +---+------------+ | 小部件 |侧边栏视图 | |页眉视图 | |项目列表视图 | | 浏览量:|--------------| |---------------| |---------------| | |一边| |标题 | | ul | | | | | | | | | | | | | | | | +--------------+ +--------------+ +------------+---+ | | | v | +--------+---+ |ItemAsLiView| |------------| |李 | | | +------------+

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

    todos.js

    在 Todos 示例中,开发人员决定 Todo 模型实例应该依赖于相应的 TodoView 实例。当TodoView 被实例化时,它会在相应的模型实例上创建一个属性view 并将自己分配给它。以便some_todo_model.view 可以访问它。不过需要注意的是,model.view 只使用一次——在Todo 模型的clear() 方法中,用于在模型被清除时移除视图实例。

    我认为 特定的依赖是不必要的。但是,对于这么小的应用程序,它可能还可以。

    我在视图中找不到任何访问this.model.view 的示例,因此无法对此发表评论。

    另见

    【讨论】:

    • 如果可以的话+100 - 继续加零!!!敬虔在答案中是明显的:)谢谢斯斯苏斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯斯:) span>
    • @Anton: this.model.view可以在TodoView的初始化方法中找到 --> initialize: function() { _.bindAll(this, 'render', 'close'); this.model.bind('change', this.render); this.model.view = this; }
    • 很好的答案。此外,this.model.view 不应用作模型不应依赖或访问视图(model.trigger('evName')view.model.bind('evName', view.function) 应该可以解决问题)
    • @Nupul,是的,这就是新视图将自己分配给模型的地方。我的意思是我在视图代码中找不到任何通过模型实际访问 视图的示例。无论如何,这将是一件奇怪的事情。没关系。
    • @AntonStrogonoff 有没有在线应用或工具来绘制这个箭头图?
    猜你喜欢
    • 2019-01-08
    • 2012-07-17
    • 2019-02-03
    • 2010-09-21
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多