如何让一个视图意识到另一个视图的变化?

时间:2012-05-22 07:13:19

标签: backbone.js

假设您正在制作音乐库应用。

您有一个带有流派列表的视图,另一个带有所选流派的内容。当用户单击列表中的类型时,其他视图中的内容应相应更新。

执行此操作的最佳方法是什么,以便存在最小的依赖关系?

我没有找到任何其他地方来听鼠标点击而不是绘制单个流派的视图。我可以从那里发送一个事件,但是获得该事件以更新绘制类型内容的其他视图的最佳方式是什么?谁应该听取该事件,流派内容视图或其集合?

编辑:我从应用程序的路由器实例化了两个视图,我确实设法通过让视图相互了解来实现这一点,但当然这不是最佳的。

2 个答案:

答案 0 :(得分:14)

你可以创建一个简单的模型来保存应用程序状态,你不需要任何花哨的东西,只需要一袋实现通常的Backbone事件方法的数据:

var AppState  = Backbone.Model.extend({});
var app_state = new AppState();

然后类型列表视图会侦听点击事件(就像您已经拥有的那样)并在有人更改时在应用状态模型上设置当前类型:

var Genres = Backbone.View.extend({
    //...
    choose: function(ev) {
        // This would be the click handler for the genre,
        // `.html()` is just for demonstration purposes, you'd
        // probably use a data attribute in real life.
        app_state.set({genre: $(ev.target).html() });
    },
});

单个类型的视图会在app-state模型上侦听"change:genre"个事件,并在类型发生变化时做出反应:

var Genre = Backbone.View.extend({
    initialize: function() {
        _.bindAll(this, 'change_genre');
        app_state.on('change:genre', this.change_genre);
    },
    //...
    change_genre: function() {
        // Refill the genre display...
    }
});

演示:http://jsfiddle.net/ambiguous/mwBKm/1/

您可以为所需的任何数据创建模型,模型是在Backbone中处理数据事件的便捷方式。作为一个额外的好处,这种方法可以很容易地保持应用程序的状态:只需将常用的Backbone持久性支持添加到AppState,然后就可以了。


如果您只需要一个简单的事件总线来推送非数据事件,您可以使用Backbone的Events方法来构建一个简单的事件聚合器:

app.events = _.extend({}, Backbone.Events);

然后,假设您有一个全局app命名空间,您可以这样说:

app.events.on('some-event', some_function);

app.events.trigger('some-event', arg1, arg2, ...);

答案 1 :(得分:1)

我见过的最好的方法是Derick Bailey提出的方法。简而言之,您可以创建一个事件聚合器,它提供了一个集中对象,用于引发不同视图可以订阅的事件。这个解决方案的优点在于它使用Backbone现有的事件系统非常简单。