3

请考虑以下场景:

<ParentView>
     <FilterSubview></FilterSubview>
     <ListSubview></ListSubview>
</ParentView>

举个例子:我有一个视图,它依次显示带有过滤器的视图(用户可以选择显示书籍、杂志或两者)和带有项目的列表。filter 和 list 都有对应的模型。过滤器 - 我们可以过滤什么。列表 - 所有项目的列表。

用例:用户看到完整列表,然后可以通过仅选择所需类别来过滤结果。

问题:

  • 这两个视图应该如何交互?他们应该互相了解还是应该由父视图处理?
  • 谁应该存储过滤列表以显示?它可以是直接列出子视图模型,也可以是父视图可以过滤完整列表,然后将其传递给渲染。
4

1 回答 1

6

您的问题没有一个正确答案,但我将尝试在这里解释一种常见的惯用方式。

两个兄弟视图不应该互相认识。相反,他们应该通过某种中介通过事件进行交互。由于在您的情况下,两者都FilterView共享ListSubView一个负责渲染它们的公共父视图,因此您可以让父视图调解事件:

var ParentView = Backbone.View.extend({
  initialize: function() {
      this.listenTo(this.filterView, "filter", this.filterChanged);
  },
  filterChanged: function(filterValue) {
      this.listSubView.filter(filterValue);
  }
});

var FilterView = Backbone.View.extend({
  events: {
      "change .filter" : "filterValueChanged"
  },
  filterValueChanged: function() {
      var filterValue = //get filter value...
      this.trigger("filter", filterValue);
  }
});

或者(最好,甚至)你可以去掉一个中间人并使用中介者模式。为此,您需要第三个组件,其工作是在不应该相互了解的各方之间传递消息。如果您使用的是 Backbone 0.9.9,则内置了这样一个中介:Backbone根对象为此目的充当全局事件总线。

所以:

//ListSubView
this.listenTo(Backbone, "listfilterchanged", this.filterChanged);

//FilterView
Backbone.trigger("listfilterchanged", filterValue);

然后是谁应该对列表数据负责的问题。我倾向于让最专业的组件负责,但只有一个组件负责。在您的情况下,这意味着ListSubView应该管理过滤列表,但前提是ParentView不需要对其进行操作。不过,这只是一个概括,所以对它持保留态度,做适合你情况的事情。

于 2013-01-16T20:35:36.097 回答