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

xytpbqjk  于 2023-05-29  发布在  其他
关注(0)|答案(4)|浏览(171)

我有一个带有多个backbone.js视图的单页Web应用程序。这些视图有时必须相互通信。举两个例子:
1.当有两种方式同时以不同方式呈现集合的视图时,在一个视图中单击项目必须中继到另一个视图。
1.当用户转换到流程的下一阶段时,第一个视图将数据传递给第二个视图。
为了尽可能地解耦视图,我目前使用自定义事件来传递数据($(document).trigger('customEvent', data))。有没有更好的办法?

kmbjn2e3

kmbjn2e31#

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

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。
希望这有帮助!

tgabmvqs

tgabmvqs2#

我同意@jakee在第一部分

var vent = {}; 
_.extend(vent, Backbone.Events);

然而,使用“on”侦听全局事件可能导致内存泄漏和僵尸视图问题,并且还导致多个动作处理程序调用等。
在视图中应该使用“listenTo”而不是“on”

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

因此,当您通过view.remove()删除视图时,此处理程序也将被删除,因为处理程序绑定到您的视图。
触发全局事件时,只需使用

vent.trigger("someEvent",parameters);
bq9c1y66

bq9c1y663#

jakee's answer建议了一种我自己使用过的好方法,但还有另一种有趣的方法,那就是将对对象的引用注入到每个视图示例中,注入的对象反过来包含对您想要聚合的任意多个视图的引用。
本质上,视图聚合器是一种“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);
    }
);
mrfwxfqh

mrfwxfqh4#

视图之间不应相互通信。从Backbone文档中:
视图是用户界面的原子块。(https://backbonejs.org/#Model-View-separation)
每个视图在其自己的DOM元素内管理呈现和用户交互。如果你严格禁止视图访问外部,这将有助于保持界面的灵活性--允许视图在任何可能需要的地方单独呈现。(https://backbonejs.org/#View-rendering)
为了保持视图的原子性和自包含性,它们应该只通过共享模型(或多个模型)进行通信。
在问题中的示例一中,视图可以共享一个具有名为“clickedItem”的属性的模型。当在view 1中点击一个项目时,它将设置共享模型的'clickedItem'属性,然后view 2将通过 Backbone.js 通知这一点。
类似地,在示例2中,您应该将数据传递给一个共享模型。

相关问题