我的问题涉及这个 UI 示例。
在管理各种 UI View 组件的“选定”状态时遇到问题。例如,我有上面的菜单,用户可以从中进行各种选择。这些选择会导致菜单本身的更新(HL 选择的项目),也会导致结果的更新,这将基于所做的选择。此外,菜单有不同种类的规则。例如,一次只能选择一个“列表”,但可以选择多个“标签”。
我正在考虑的一种方法是创建一个保存 UI“选择”状态的 Backbone 模型。例如,我可以有一个模型 SearchCriteria 来保存这些信息。然后,当用户在 UI 中做出选择时,我可以更新这个模型。我可以让各种 View 组件监听此模型中的更改(以及主要数据模型中的更改)。然后, View 将通过更新显示为选中的项目来更新其视觉状态。
我在这种方法中苦苦挣扎的一个项目是谁应该负责更新项目的选定状态。例如,在标签列表中,我可能定义了以下部分......
我是不是该...
抱歉问了这么多问题。我只是很难转向这种发展模式。
最佳答案
你几乎得到一个类似于我会使用的答案。
如果您欣赏 list
, search
, due
和 tags
是对大量待办事项的搜索过滤器,您已经完成了 90% 的启蒙之路。事实上,除了 search
,所有这些都只是“各种标签”! (除非您有 10,000 个待办事项,否则没有与性能或内存相关的理由来列出待办事项列表;“工作”、“项目 #1”和“个人”只是您使用的专用标签过滤掉您的 View 中的项目,仅显示与您生活的一个或另一个领域相关的项目。)
创建 SearchCriteria 模型。 (从技术上讲,您不是在搜索,而是在过滤:您从 View 中排除了那些与您的搜索条件不匹配的东西。)该模型将包含有关您的客户端状态的许多属性。您的搜索条件几乎完全由客户端中存在的数据驱动(因为搜索一次仅适用于一个 ToDoList),因此它完全与 SearchCriteria 相关,而不是与 ToDo 对象相关。
所有 View 都绑定(bind)到 SearchCriteria 上的更改/添加/删除事件。当用户单击任何 View (列表、 View 、标签)时,该消息将转发到 SearchCriteria。它会进行适当的内部更改,进而触发 View 重新呈现自己。主 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 可以进行附加。那是口味问题。我都做过。
您必须深入研究 Backbone 的父库,下划线,才能了解
_.each()
的本质美妙之处。用法。此外,我经常将整个 Backbone 应用程序包含在一个自动执行的匿名函数中,并将“searchCriteria”作为变量保留给 SEAF 范围内的所有对象,因此它不会是
this.searchCriteria
, 但只是 searchCriteria
.您还可以编写 SearchCriteria 以便它调用同步,将事件状态写入服务器,然后您可以将其保存为原始 JSON 对象;同步的好处是,如果您发送的内容和接收的内容相同,则不会触发任何事件,因此您不会获得双重渲染效果,而使用 JSON 的好处是它适合客户端,但不包含服务器的 ToDo 关系关心的任何内容。
此外,您可以指定特定的客户端行为规则。例如:当您更改待办事项列表时,您可以应用文本搜索条件,或者,您可以决定更改列表清除文本搜索条件字段;这样做将触发一个事件,该事件将导致“TextSearchView”清除其输入框(您必须编写该事件处理程序,但很明显您打算这样做)。您可以制定任何您喜欢的规则,例如“更改列表会清除所有选择”,但这似乎并不明智。我可以很容易地想象尝试解决我的“项目”列表和个人生活中的错误。但是清除搜索框似乎更……明智,如果你明白我的意思的话。
关于Backbone.js 方法来管理 UI 状态/处理 UI 中的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6309946/