微风 - 如何订阅多对多关系的变化

时间:2013-06-04 20:15:49

标签: angularjs breeze

我在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),但这会产生循环引用错误。)

1 个答案:

答案 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对实体的所有引用)。在我看来,这是适当的终身管理。