我在Breeze中有多对多的关系:
Product *---1 ProductWidgets 1----* Widgets
产品需要知道其中任何一个小部件何时发生变化。可以随时在产品中添加或删除小部件。
理想情况下,我想做类似的事情:
product.widgets.on('change', function () {});
...但我想我需要的东西是:
var handleWidgetChange = function (changes) {
console.log("here are the changes", changes);
};
for(var i = 0; i < product.productWidgets.length; i++) {
// make sure we're getting events for the current set of widgets
product.productWidgets[i].widget.entityAspect.propertyChanged.subscribe(handleWidgetChange);
// if any of the current set of product widgets gets pointed elsewhere, catch that
product.productWidgets[i].entityAspect.propertyChanged.subscribe(function (change) {
if (change.propertyName === "widget") {
change.oldValue.entityAspect.propertyChanged.unsubscribe();
change.oldValue.entityAspect.propertyChanged.subscribe(handleWidgetChange);
}
})
}
// handle new product widgets and removal of product widgets
product.productWidgets.arrayChanged.subscribe(function (change) {
if (change.added) {
change.added[0].widget.entityAspect.propertyChanged.subscribe(handleWidgetChange);
} else if (change.removed) {
change.removed[0].widget.entityAspect.propertyChanged.unsubscribe();
}
});
是否有推荐的方法来实现这一目标?
(注意:我正在使用角度,并且只想$watch('product.productWidgets', function () {}, true)
,但这会产生循环引用错误。)
答案 0 :(得分:0)
内存泄漏在JavaScript中是一个巨大的风险,部分原因是没有弱引用。你必须小心事件。你真的不想迭代添加和删除订阅的实体。
您也不希望使用Angular手表来监控模型更改,因为您可以将UI性能推向地面。有太多的实体拥有太多的属性,你应该在看完之后很久就将手表留在原地,这肯定会弄错。
幸运的是,Breeze提供了一个中央实体变更监控设施。 A Breeze EntityManager
侦听它在缓存中保存的任何实体的更改。
var widgetType = manager.metadataStore.getEntityType('Widget'); var productWidgetType = manager.metadataStore.getEntityType('ProductWidget'); entityManager.entityChanged.subscribe(entityChanged); function entityChanged(changeArgs) { var entity = changeArgs.entity; if (entity.entityType === productWidgetType || entity.entityType === widgetType) { // do what you do when someone does something to an entity of this type // perhaps call back into a method on that instance that knows what to do entity.somethingChanged(changeArgs.entityAction); } }
此事件会通知您对经理缓存中任何实体的任何更改。它将被频繁调用,因此您的评估会很清晰。例如,考虑在查询期间停用事件处理程序。
changeArgs.entityAction
告诉您实体发生了什么。触发此事件的操作有很多:属性可能会更改,EntityState
可能会更改(添加/修改/删除/分离)等。
您不必担心product.productWidgets
数组。当从该数组中添加或删除ProductWidget
时,ProductWidget.productId
外键将会更改...并且您将在此entityChanged
处理程序中选择该项。
没有必要担心内存泄漏,因为EntityManager
已经拥有对实体的引用,并且将继续执行此操作,直到您分离实体或处置EntityManager
实例(和您自己或UI对实体的所有引用)。在我看来,这是适当的终身管理。