相关的Backbone.js视图是否应该相互引用,或仅通过事件进行交谈?

时间:2012-01-09 15:47:01

标签: javascript backbone.js eventaggregator

我有一个应用程序为Collection Models执行CRUD。每个模型都有DisplayView,始终可见。还有EditView只有在点击相关联的DisplayView时才可见。

DisplayViewEditView出现在不同的父视图中。现在我正在使用“事件聚合器”模式告诉我的应用程序在单击EditView时呈现DisplayView。此处描述的模式:http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/

当我点击DisplayView之一时,它会触发EditViews的父级监听的事件。收到此事件后,它会根据触发事件的模型呈现相应的EditView

这适用于我的大多数应用程序,但如果我想根据应用程序中相关EditView的绝对位置获得DisplayView更改位置,则会特别麻烦。而不是让DisplayView直接控制EditView的位置,而是触发“请将自己重新定位到这些坐标”事件。这种直接通信并不像应该向整个应用程序广播的东西。我开始怀疑,对于我的情况,我应该只引用相应的EditView作为每个DisplayView的属性,而不是将它们分离。

正如我所说,问题在于它们是在不同的父视图中呈现的。 DisplayViews呈现HeaderView,同时EditViews呈现ContentView

其他人如何处理这样的情况? EditView在某些方面属于DisplayView,但这与我的应用程序的DOM结构不匹配。假设我确实在每个EditViewDisplayView之间创建了直接链接,我该如何处理EditView的显示/隐藏? DisplayView是否还需要对ContentView容器的引用,它会使用适当的EditView作为参数显式呈现?

3 个答案:

答案 0 :(得分:15)

尽可能地,绝对避免持有对并行视图的引用(与父/子视图相反)并相互修改的视图,这很快就会变成意大利面并使您的代码更加脆弱。相反,以下模式允许您的不同视图保持分离,同时仍然可以完成工作。

全球通知/活动

这是你提到的那个。它的工作原理,但就像你提到的那样不太优雅,因为它不必要地在全球范围内广播

绑定/观察者模式

在控制器中创建一个名为editViewPosition的对象,并公开方法让显示视图更改editViewPosition的值。然后,EditView可以监听并观察editViewPosition中的更改并相应地更新自身。这种方法的优势在于,以后您可以让5个不同的EditViews在您的控制器上观察相同的属性editViewPosition并相应地更新自己,并且您的{{1}中无需更改任何内容为了那个发生。

委托模式

您可以允许显示视图具有DisplayView属性,而不是直接连接视图和调用方法,控制器可以将其设置为delegate视图。当edit想要更新其编辑视图时,它将检查其委托是否存在并实现预定义函数,如果是,它将调用该函数。这种方法比观察者模式更加耦合,但仍允许高度去耦(后来例如你可以在那里交换完全不同的视图而不是你的编辑视图,程序应该仍然可以工作。)这种方法的弱点是您通常只有一个委托,但它比任何其他提到的模式更直接。

手动维护要通知的对象列表

这几乎是委托模式的扩展。基本上,您在显示视图中有一组DisplayView个类似的对象,并且在需要时,您的显示视图将遍历每个对象上的数组和调用方法。该阵列将再次由您的控制器填充。

结论

就个人而言,我最有可能使用绑定和观察者模式作为您的用例。通常,并行的视图(没有直接的父/子关系)不应该保持彼此的引用,并且应该仅通过它们共享的公共控制器/事件/通知/其他超级结构进行通信。

答案 1 :(得分:1)

除了Tony列举的那些选项之外,还有另一个选项,即“冒泡”在DisplayView被点击到DisplayView的最近共同父视图时触发的事件EditView。通过该事件,您可以传递显示视图的坐标及其代表的模型。然后,公共父级直接调用EditView上的方法来重新定位它并呈现正确的模型。因此,并行视图之间没有明确的引用,也没有全局变量。

使用主干内置的triggerlistenTo方法,多个视图层的冒泡事件变得混乱,但Backbone.Courier插件使其非常直接:

https://github.com/rotundasoftware/backbone.courier

答案 2 :(得分:0)

如果您已经将应用程序解耦,请保持这种方式。在视图之间引入直接依赖关系将使您的应用程序不易维护,并且整体上更令人沮丧。

事件是去这里的方式。