Backbone.js:视图间通讯

32

我正在开发一个Backbone应用程序,其中包含一个条目列表,类似于示例应用程序Todos (http://documentcloud.github.com/backbone/examples/todos/index.html)。

因此,我有一个App视图和一个每个列表项的视图。现在,假设我有一个全局编辑按钮。 App视图将处理单击事件,然后我想要做的是告诉每个列表视图显示删除按钮。

在下面来自Spotify的截图中,按下“编辑”按钮会导致所有列表视图的外观改变。

使用Backbone的最佳方法是什么? 我需要遍历所有列表视图并调用editMode函数。 但是,App视图(默认情况下)不知道列表视图。

enter image description here


3
我来这里就是想问这个完全相同的问题,碰巧在我的首页上看到了你的问题...有点吓人。 - aw crud
2个回答

41

我之前写过一篇文章,介绍了几种不同的协调视图之间的选项:http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/

对于你的情况,我建议使用我在那篇文章中介绍的事件聚合器。你可以让每个项目视图监听“editmode”事件或类似的事件。当此事件触发时,每个视图都会更新自己以进入编辑模式。然后当你点击“完成”时,发送一个“viewmode”事件或类似的事件,让每个视图适当地更新自己。


1
假设在问题的示例中,每个曲目视图都有对曲目集合的引用。可以直接使用该集合或通过支持每个曲目视图的曲目模型属性来发送“editmode”事件吗?这样就不需要单独的事件对象来实现此功能。 - aw crud
1
“错误”这个词非常主观。它取决于您的应用程序涉及的复杂性以及您的应用程序需要达到多么解耦的程度。您可以首先通过集合传递它,看看是否适合您。如果您发现所有事情都紧密耦合在一起,则重构以使用单独的事件对象。 - Derick Bailey
@DerickBailey - 我真的很喜欢你在文章中描述的模式。谢谢分享。 - UpTheCreek
6
Sheepdog 的 Thurloat 发布了一个非常鼓舞人心的对你解决方案的扩展,他建议使用“视图工厂”。他的建议可以实现以下两点改进:1)消除了需要显式传递 eventBus 到每个视图(或声明全局 eventBus)的需求;2)以声明性的 Backbone 方式声明全局事件绑定,从而极大地提高了可读性。这是完整的文章链接:http://thurloat.com/2012/01/21/backbonejs-readable-modular-testable-views - 该文章使用 CoffeeScript 编写。 - SunnyRed
我遇到了类似的问题,喜欢你的事件聚合器想法。谢谢。 - zsitro
Derick,你对于使用Backbone.Babysitter库有什么看法呢?显然,列表视图必须要使用babysitter,但是如果认可这一点,那么通过在列表上代理“setMode”方法到每个单独的列表项视图上,使用babysitter的“call”方法会非常干净利落。 - Brave Dave

2

个人意见:使用backbone.js,你可以进行一个简单的“hack”,实现视图间的发布/订阅通信:

类似以下代码(未经测试):

var EventBus = Backbone.Model.extend({

   publish: function(event, args){

       this.trigger(event, args);

   },

   subscribe: function(event, args) {

       this.bind(event, args);

   }
});

你基本上已经明白了。现在对于每个视图,都让它“绑定”到这个EventBus上(因为在backbone中,视图只能绑定到模型/集合中),你只需使用方法名称publish/subscribe与此类模型的命名方式保持同步,但你也可以选择不这样做。在这种情况下,只需创建一个空的EventBus“类”,然后让每个视图都绑定到它上面 :)
因此,每个视图只需要与这个EventBus耦合并对接收到的事件进行操作!Backbone.js在内部处理了这个设计模式的所有管道,所以你几乎是免费得到它的 :)
上面的代码可能无法直接运行,但是它可以让你对此有一个大致的了解...

1
既然已经有了Backbone.Events,为什么不保持DRY呢? - opengrid
@opengrid - 这是针对v0.5.1的。当时“如何使用事件”并没有得到很好的宣传 :) - PhD
1
只是说“你基本上明白了”而不清楚地解释你的意思并不是很有用,对于那些试图寻找答案的人来说,这可能比有帮助更加令人沮丧。 - Pea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接