0

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

4

1 回答 1

0

内存泄漏在 JavaScript 中是一个巨大的风险,部分原因是没有弱引用。你必须小心事件。您真的不想迭代添加和删除订阅的实体。

您也不想使用 Angular 监视来监视模型更改,因为您会将 UI 性能推向底层。具有太多属性的实体太多了,在您应该停止观看很久之后将手表留在原处,您肯定会犯错误。

幸运的是,Breeze 提供了一个中央实体更改监控工具。BreezeEntityManager监听它在缓存中保存的任何实体的更改。

var widgetType = manager.metadataStore.getEntityType('Widget');
var productWidgetType = manager.metadataStore.getEntityType('ProductWidget');

entityManager.entityChanged.subscribe(entityChanged);

功能实体改变(changeArgs){
    var 实体 = changeArgs.entity;
    if (entity.entityType === productWidgetType ||
        entity.entityType === widgetType) {
       // 当有人对这种类型的实体做某事时做你做的事情
       // 可能会回调该实例上知道该做什么的方法
       entity.somethingChanged(changeArgs.entityAction);
    }          
}

这一事件会通知您管理器缓存中任何实体的任何更改。它会被频繁调用,因此您的评估要清晰。例如,考虑在查询期间停用您的事件处理程序。

changeArgs.entityAction告诉你实体刚刚发生了什么。触发此事件的操作有很多:属性可能会更改,它EntityState可能会更改(添加/修改/删除/分离)等。

您不必担心product.productWidgets数组。当ProductWidget从该数组中添加或删除 a 时,外键将更改……您将在此处理程序ProductWidget.productId中拾取它。entityChanged

无需担心内存泄漏,因为它EntityManager已经持有对实体的引用,并将继续这样做,直到您分离实体或处置EntityManager实例(以及您自己或 UI 对实体的所有引用)。在我看来,这是适当的终身管理。

于 2013-06-05T01:40:59.083 回答