如何在同一个父母的两个看似独立的观点互动

Ily*_*yev 3 backbone.js

请考虑以下情况:

<ParentView>
     <FilterSubview></FilterSubview>
     <ListSubview></ListSubview>
</ParentView>
Run Code Online (Sandbox Code Playgroud)

给你举个例子:我有一个视图,它反过来显示带过滤器的视图(用户可以选择显示书籍,杂志或两者)和带有项目的列表.过滤器和列表都有相应的型号.过滤 - 我们可以过滤什么.列表 - 所有项目的列表.

用例:用户可以看到完整列表,然后只需选择所需的类别即可过滤结果.

问题:

  • 这两个观点应该如何互动?他们应该了解彼此还是应该让父母看待它?
  • 谁应该存储过滤列表才能显示?它可以是直接列表子视图模型,或者父视图可以过滤完整列表,然后将其传递给渲染.

jev*_*lio 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);
  }
});
Run Code Online (Sandbox Code Playgroud)

或者(最好是偶数)你可以剪掉一个中间人并使用Mediator模式.为此,您需要第三个组件,其任务是在不应该彼此了解的各方之间传递消息.如果您正在使用Backbone 0.9.9,那么内置的是这样的中介:Backbone根对象用作此目的的全局事件总线.

所以:

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

//FilterView
Backbone.trigger("listfilterchanged", filterValue);
Run Code Online (Sandbox Code Playgroud)

然后是谁应该负责列表数据的问题.我倾向于让最专业的组件负责,但只有一个组件负责.在您的情况下,这意味着ListSubView应该管理已过滤的列表,但前提是ParentView不需要对其进行操作.这只是一个概括,所以请耐心等待你的情况.