backbone.js - 如何在视图之间进行通信?

时间:2012-07-23 09:31:06

标签: javascript backbone.js

我有一个包含多个backbone.js视图的单页Web应用程序。这些观点有时必须相互沟通。两个例子:

  1. 当有两种方式同时以不同方式呈现集合时,必须将一个视图中的项目单击转发到另一个视图。
  2. 当用户转换到流程的下一个阶段并且第一个视图将数据传递给第二个阶段时。
  3. 要尽可能地分离视图,我目前使用自定义事件来传递数据($(document).trigger('customEvent', data))。有一个更好的方法吗?

3 个答案:

答案 0 :(得分:14)

一种广泛使用的技术是扩展Backbone.Events对象以创建您的个人全局事件聚合器。

var vent = {}; // or App.vent depending how you want to do this
_.extend(vent, Backbone.Events);

根据您是否使用requirejs或其他内容,您可能希望将其分隔为自己的模块或将其作为Application对象的属性。现在,您可以在应用中的任何位置触发和收听事件。

// View1
vent.trigger('some_event', data1, data2, data3, ...);

// View2
vent.on('some_event', this.reaction_to_some_event);

这也允许您使用事件聚合器在模型,集合,路由器等之间进行通信。Here is Martin Fowler's concept for the event aggregator(不是在javascript中)。这是一个更多的backboney实现和反思这个主题,更多的是Backbone.Marionette,但大部分都适用于vanilla Backbone。

希望这有帮助!

答案 1 :(得分:8)

我同意@jakee的第一部分

var vent = {}; 
_.extend(vent, Backbone.Events);
然而,用" on"听一个全球性的事件。可能会导致内存泄漏和僵尸视图问题,并且还会导致多个操作处理程序调用等。

而不是" on",你应该使用" listenTo"在你看来

 this.listenTo(vent, "someEvent", yourHandlerFunction);

因此,当您通过view.remove()删除视图时,此处理程序也将被删除,因为处理程序已绑定到您的视图。

触发全局事件时,只需使用

即可
vent.trigger("someEvent",parameters);

答案 2 :(得分:0)

jakee's answer建议我自己使用的一种很好的方法,但还有另一种有趣的方法,那就是将一个对象的引用注入到每个视图实例中,注入的对象依次包含对as的引用。你希望聚合的许多观点。

本质上,view-aggregator是一种“App”对象,可以附加视图旁边的东西,例如集合。它确实涉及扩展视图,因此可能不是每个人的口味,但另一方面,扩展是一个简单的例子。

我使用http://arturadib.com/hello-backbonejs/docs/1.html的代码作为我的ListView的基础,然后我得到了以下工作:

define(
    ['./listView'],

    function (ListView) {
        var APP = {
            VIEWS : {}
        }

        ListView.instantiator = ListView.extend({
            initialize : function() {
                this.app = APP;
                ListView.prototype.initialize.apply(this, arguments);
            }
        });

        APP.VIEWS.ListView = new ListView.instantiator();
        console.log(APP.VIEWS.ListView.app);
    }
);