Backbone.js - 在哪里存储状态信息?

Posted

技术标签:

【中文标题】Backbone.js - 在哪里存储状态信息?【英文标题】:Backbone.js - where to store state information? 【发布时间】:2011-10-26 13:11:58 【问题描述】:

我是Backbone.js 的新手,我正试图找出状态变量应该放在哪里。我的用例:

我有一个为一本书提供阅读界面的应用程序(我知道,经典示例,对吗?)。我的模型是BookPage,每个模型都有集合类。应用程序的结构大致如下(原谅 ASCII visio):

+------------+
| Controller |
+------------+
    |      Views                 Models
    | +--------------+      +----------------+
    |-|  IndexView   |------| BookCollection |
    | +--------------+      +----------------+
    |                               |
    | +--------------+      +----------------+
    +-|   BookView   |------|     Book       |
      +--------------+      +----------------+
       |                            |
       | +--------------+           |
       |-|  TitleView   |-+         |
       | +--------------+ | +----------------+
       |                  +-|     Page       |
       | +--------------+ | +----------------+ 
       +-|   PageView   |-+
         +--------------+ 

也就是说,Controller 实例化并协调两个视图,IndexViewBookView,由模型支持。 BookView 实例化和协调一组子视图(实际上比这里显示的更多)。

状态信息包括:

当前图书(指针或 ID) 当前页面(指针或 ID) 其他 UI 状态变量,例如页面上的图像是否可见,其他小部件是否打开或关闭等。

我的问题是,这个状态信息应该放在哪里?可能的选项包括:

模型,可以感知状态。这是有道理的,因为它们旨在存储数据,并且视图可以监听状态变化,但这似乎不符合预期的 Backbone.js 模式,并且并不总是有意义(例如,在PageView 应该适用于所有页面,而不仅仅是当前页面)

用于保存状态信息的特殊单例模型。同样,这很有意义,易于收听,所有视图都可以绑定到它 - 但同样,这似乎超出了标准 MVC。

视图,负责 UI 状态 - 但这需要视图相互了解才能获取状态信息,这似乎不正确

控制器,应该在状态之间路由应用程序 - 这是有道理的,但它意味着有点奇怪的往返,例如User selects "Show Images" --> View event listener is called --> View informs Controller --> Controller updates state --> Controller updates View(而不是更简单的User selects "Show Images" --> View event listener is called --> View updates

我想在某些方面这是一个通用的 MVC 问题,但我很难理解它。 应用程序的哪个部分应该负责保存当前状态?

更新:为了将来参考,我使用了一个全局单例状态模型来解决这个问题。 UI 流程是这样的:

    视图 UI 处理程序除了更新 app.State 什么都不做 我的路由器除了更新 app.State 之外什么也不做 - 它们本质上是专门的视图,用于显示和响应 URL 更改 视图监听 app.State 上的更改并相应更新

我的应用是开源的 - 你可以看到code on Github。这里的相关部分是State model,我已经对其进行了扩展以处理 URL 的(反)序列化状态。

【问题讨论】:

主干0.5中没有Controller 嗯,是的,我有一个路由器类,我正在调用Controller。它仍然基本上是为了执行控制器的功能,对吧? 并非如此。就经典 MVC 而言,您应该将 View 视为经典的 Controller。做主干的时候最好不要去想经典的MVC。就您的问题而言,当前书籍进入AppView,当前页面进入Book,其余进入AppViewAppView 是一个特殊的单例视图,如果你愿意的话 按照这个逻辑,当前页面不会进入BookView,而不是Book吗? 【参考方案1】:

Don't limit your Backbone apps to Backbone constructs。如果您发现您的应用需要某些功能,但不能很好地融入其中一种 Backbone 结构,请不要为了将所有内容都保留在 Backbone 中而将其硬塞进一个结构中。

我发现backbone boilerplate 在这方面很有帮助。它为您设置模块并为您提供扩展 Backbone.Events 的应用程序对象(如之前链接的文章中所示)。此应用程序对象可用于存储实例化模型、视图和控制器/路由器,您应该随意将自己的非主干模块添加到应用程序对象,以处理不完全适合其中之一的职责骨干结构。

【讨论】:

感谢您的链接。这实际上与我所做的并不太远 - 例如请参阅my app initialization,这与链接的内容非常相似。但就事件和侦听器而言,Backbone确实有助于状态模型。你可以看到my implementation here。【参考方案2】:

为什么不创建一个状态模型来存储和描述当前状态呢?我不认为这是错误的。由于当前状态涉及多个模型,我认为创建一个状态模型来存储和接收当前状态是合理的。

然后控制器可以与状态模型通信以获取当前状态。 UI 状态应该存储在相应的模型中。状态模型知道哪本书和哪一页,然后书籍和页面模型会跟踪它们当前的 UI 状态。

【讨论】:

这或多或少是我决定采用的方式,但我完全放弃了控制器 - 视图更新 UI 事件的状态模型,然后侦听状态更新以更新 UI,并且路由器对 URL 执行相同的操作。 酷。我在 Rails 应用程序中遇到了类似的问题。不真正适合任何现有模型或控制器的功能已通过新模型解决,这也有助于应用保持“RESTful”。

以上是关于Backbone.js - 在哪里存储状态信息?的主要内容,如果未能解决你的问题,请参考以下文章

Backbone.js:查看状态和路由

Backbone.js - 在视图处于活动状态时添加 keydown 事件?

Backbone.js 状态管理/基于 url 片段的视图初始化

Backbone.js 本地存储,从服务器预先加载

Backbone.js:组合多个模型的复杂视图

Backbone.js:设置本地存储只需一行?