Backbone.js在UI中管理UI状态/处理选择的方法

时间:2011-06-10 17:24:33

标签: backbone.js

我的问题涉及此UI示例。

enter image description here

管理各种UI视图组件的“选定”状态的方法有问题。例如,我有上面的菜单,用户可以从中进行各种选择。这些选择应该导致菜单本身的更新(HL选择的项目)并且还导致结果的更新,这将基于所做的选择。此外,菜单有不同的规则。例如,您一次只能选择一个“列表”,但可以选择多个“标记”。

我正在考虑的一种方法是创建一个支持UI“选择”状态的Backbone模型。例如,我可以拥有一个包含此信息的模型SearchCriteria。然后,当用户在UI中做出选择时,我可以更新此模型。我可以让各种视图组件监听此模型中的更改(以及主数据模型中的更改。)然后,视图将通过更新哪些项目显示为已选择来更新其可视状态。

我在这种方法中遇到的一个问题是谁应该负责更新项目的选定状态。例如,在标签列表中,我可能会定义以下部分......

  • 标签(代表标签的型号)
  • TagCollection(代表标签集合的集合)
  • TagMenuView(代表可供选择的标签菜单的视图)
  • TagMenuItemView(代表菜单中单个项目的视图)

我应该......

  • 在TagMenuItemView上设置一个事件监听器以进行单击,然后尝试处理1)更新SearchCriteria模型,以及2)更新菜单的可视状态,例如,选定的项目?
  • 或者,我是否应该使用更高级别的视图(TagMenuView)监听用户选择标记等事件,并在那里执行工作?
  • 此外,此示例中的标签菜单允许选择多个项目,但列表菜单一次只允许选择一个列表。这个“UI”规则(或者这是否真的是与搜索相关的业务规则?)将在何处执行?例如,如果我在每个单独的列表菜单项上听取了单击事件,我当然可以更新该项目的可视状态,但是,我还需要确保更高级别的菜单视图取消选择任何其他所选列表。那么,管理视图中的待办事项列表菜单的“UI”状态会更好吗,这些菜单代表整个菜单(ToDoListMenuView)而不是每个菜单项视图?

很抱歉这么多问题。我只是很难转向这种发展模式。

1 个答案:

答案 0 :(得分:8)

你几乎得到了一个类似于我将使用的答案。

如果您感谢listsearchduetags搜索过滤器的大量待办事项,那么您是开悟道路的90%。事实上,除了search之外,所有这些都只是“各种标签”! (除非您有10,000个待办事项,否则没有与性能或内存相关的原因来列出待办事项列表;“工作”,“项目#1”和“个人”只是您的专用标记过滤视图之外的项目,仅显示与您生活中的一个领域相关的项目。)

创建SearchCriteria模型。 (您在技术上没有搜索,您正在过滤:您从视图中排除那些与您的搜索条件不匹配的内容。)此模型将包含有关您的客户端状态的许多属性。您的搜索条件几乎完全由客户端中存在的数据驱动(因为搜索一次仅适用于一个ToDoList),因此它完全与SearchCriteria相关,而不是与ToDo对象相关。

所有视图绑定到SearchCriteria上的更改/添加/删除事件。当用户单击任何视图(列表,视图,标记)时,该消息将转发到SearchCriteria。它进行适当的内部更改,从而触发视图重新呈现自己。主ToDoListView中的一个事件收件人,在其呈现期间检查搜索条件。类似的东西:

ToDoListView = Backbone.View.extend({
...
render: function() {
    var self = this, 
    toDraw = this.collection.filter(
        function(c) { return this.searchCriteria.passes(c); });
    $(this.el).html('');
    _.each(toDraw, function(c) { 
        (new ToDoItemView({model: c, parent: self})).render(); });
}

这可能有点个人惯用,传入父对象并让项目将自身插入到父对象的DOM对象中。你可以传入任何东西:要追加的元素。或者,render可以返回一个DOM对象,ListView可以执行追加。这是一个品味问题。我已经做到了。

你必须挖掘一下骨干的父库,下划线,以了解_.each()用法的基本精彩。

另外,我经常在一个自动执行的匿名函数中包含一个完整的Backbone应用程序,并将“searchCriteria”保留为SEAF范围内所有对象都可以访问的变量,因此它不会是{{1 },但只是this.searchCriteria

您还可以编写SearchCriteria,以便调用sync,将事件状态写入服务器,然后将其保存为原始JSON对象;同步的好处是,如果你发送的内容和收到的内容是相同的,则不会触发任何事件,因此你不会获得双重渲染效果,使用JSON的好处是它适合客户端,但不包含服务器ToDo关系所关心的任何内容。

此外,您可以指定特定的客户端行为规则。例如:当您更改待办事项列表时,您可以应用文本搜索条件,或者,作为替代方案,您可以决定更改列表清除文本搜索条件字段;这样做将触发一个事件,该事件将导致“TextSearchView”清除其输入框(您必须编写该事件处理程序,但它显然您打算这样做)。您可以组成您喜欢的任何规则,例如“更改列表清除所有选择”,但这似乎不合理。我很容易想象在个人生活中尝试解决我的“项目”列表中的错误。但是如果你知道我的意思,清除搜索框似乎更明智......