我有一个对Collection
的Models
执行CRUD的应用程序。每个模型都有一个DisplayView
,它始终可见。还有一个EditView
,仅在单击关联的DisplayView
时可见。DisplayView
和EditView
出现在不同的父 View 中。现在,我正在使用“事件聚合器”模式来告诉我的应用程序,当单击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
的属性,而不是去耦它们。
正如我所说,问题在于它们是在不同的父 View 中呈现的。 DisplayViews
呈现在HeaderView
中,而EditViews
呈现在ContentView
中。
别人如何处理这种情况? EditView
在某种程度上属于DisplayView
,但是与我的应用程序DOM的结构方式不匹配。假设我确实在每个EditView
和DisplayView
之间创建了直接链接,我将如何处理EditView
的显示/隐藏? DisplayView
是否还需要引用ContentView
容器,它将使用适当的EditView
作为参数来显式呈现?
最佳答案
尽您所能,绝对避免 View 持有对并行 View 的引用(与父/ subview 相对)并相互修改,这会很快变成意大利面条,并使您的代码更加脆弱。取而代之的是,以下模式可让您的不同 View 保持解耦,同时仍可完成工作。
全局通知/事件
这是您提到的那个。它可以工作,但是就像您提到的那样不够优雅,因为它不必要地在全局范围内广播
绑定(bind)/观察者模式
在 Controller 中创建一个名为editViewPosition
的对象,并公开方法以使显示 View 更改editViewPosition的值。然后,EditView
可以监听并观察editViewPosition
中的更改,并相应地进行更新。这种方法的优势在于,以后您可以在 Controller 上拥有5个不同的EditViews
,它们都观察到相同的属性editViewPosition
并进行相应的更新,因此无需更改DisplayView
即可实现。
委托(delegate)模式
您可以允许显示 View 具有delegate
属性,而不是直接挂接 View 和彼此调用方法,可以由 Controller 将其设置为edit
View 。当DisplayView
希望更新其编辑 View 时,它将检查其委托(delegate)是否存在并实现预定义的函数,如果存在,则将调用该函数。这种方法比观察者模式更具耦合性,但仍然允许高度去耦(例如,以后您可以在那里交换一个完全不同的 View ,而不是编辑 View ,并且程序仍然可以工作。)这种方法的缺点是您通常只有一个委托(delegate),但是它比上面提到的任何其他模式都更直接。
手动维护要通知的对象列表
这几乎是委托(delegate)模式的扩展。基本上,您在显示 View 中有一个类似于EditView
的对象数组,并且在需要时,您的显示 View 将遍历每个对象上的array和call方法。该数组将再次由您的 Controller 填充。
结论
就个人而言,我很可能会在您的用例中使用绑定(bind)和观察者模式。通常,平行的 View (没有直接的父/子关系)不应相互引用,而应仅通过它们共享的公共(public) Controller /事件/通知/其他 super 结构进行通信。