Breeze 如何检测对实体的更改';什么是实体状态?

Breeze 如何检测对实体的更改';什么是实体状态?,breeze,Breeze,我想在客户列表的每一行上放置一个“删除”按钮和一个“取消”按钮。当客户“未更改”时,“取消”按钮被禁用。但是,当客户转换到更改状态(“添加”、“修改”、“删除”)时,我希望启用“取消”按钮,以便用户可以在保存之前反转更改(无论更改是什么) 我几乎可以通过订阅customer.entityAspect.propertyChanged来做到这一点。属性更改表示实体状态中的潜在更改。我可以订阅该事件,并让我的处理程序更新我添加到客户实体中的isChanged可见项。然后我将“取消”按钮启用绑定到isC

我想在客户列表的每一行上放置一个“删除”按钮和一个“取消”按钮。当客户“未更改”时,“取消”按钮被禁用。但是,当客户转换到更改状态(“添加”、“修改”、“删除”)时,我希望启用“取消”按钮,以便用户可以在保存之前反转更改(无论更改是什么)

我几乎可以通过订阅
customer.entityAspect.propertyChanged
来做到这一点。属性更改表示
实体状态中的潜在更改。我可以订阅该事件,并让我的处理程序更新我添加到客户实体中的
isChanged
可见项。然后我将“取消”按钮启用绑定到
isChanged
,我就可以开始了

但是,
propertyChanged
事件仅在数据属性发生更改时才会引发,例如,
customer.Name(“新公司”)。当用户单击“删除”按钮时,它不会引发。“Delete”触发
customer.entityAspect.setDelete()不接触数据属性;它只需更改客户的
实体状态

(1) 为什么对客户的
实体状态的更改不引起
属性的更改
和(2)如何侦听对
实体状态的更改,以便控制“取消”按钮

我用的是击倒


p.p.S:这个问题的灵感来源于前面的SO问题。

您是正确的,当
实体状态发生变化时,Breeze不会引发
属性的变化。也许应该。我们会考虑的。

Breeze在实体上也没有单独的事件-无
实体状态更改
事件-在
实体状态更改时通知您。我们已经考虑过好几次了。我们一直在说服自己不要这样做

有一个非常好的解决方案,它的性能比专用的
entityStateChanged
事件要好。现在你必须自己编写代码

诀窍是听
实体管理器
,而不是听实体。您将在示例中找到此解决方案的一个变体;在entityTest.js模块中查找“可以通过entityManager.entityChanged控制自定义的ko entityState属性”

我将调整它以适合您的示例。其实质如下:

  • 订阅
    entityManager.entityChanged
    事件;当它被引发时,原因是一个实体的
    实体状态
    发生了变化,您将更新该实体的
    isChanged
    boolean KO observable(如果该属性存在)

  • isChanged
    observable添加到应以这种方式监视的实体类型中

  • 下面是步骤1的示例:侦听状态更改

    // subscribe with handler watching for EntityState changes addEntityStateChangeTracking(manager); function addEntityStateChangeTracking(entityManager) { if (entityManager._entityStateChangeTrackingToken) { return; } // already tracking it // remember the change tracking subscription with a token; // might unsubscribe with that token in future entityManager._entityStateChangeTrackingToken = entityManager.entityChanged.subscribe(entityChanged); var entityStateChangeAction = breeze.EntityAction.EntityStateChange; function entityChanged(changeArgs) { if (changeArgs.entityAction === entityStateChangeAction) { var entity = changeArgs.entity; if (entity && entity.isChanged) { // entity has the observable var isUnchanged = entity.entityAspect.entityState.isUnchanged(); entity.isChanged(!isUnchanged); } } } }
    这一切似乎需要做很多工作。如果Breeze在
    EntityState
    更改时引发
    propertyChanged
    事件,则会更容易。我们将对此给予更多考虑。。。可能有一些很好的反驳。同时,我认为您在这里看到的是最好的方法。

    我们发现,将breeze实体管理器包装在我们自己的内部给了我们很好的灵活性,让我们可以在公园里散步,尤其是在hasChangesChanged活动中

    var EntityManager = (function () {
        function EntityManager(breezeEntityManager) {
            this.breezeEntityManager = breezeEntityManager;
            this.hasChanges = ko.observable(breezeEntityManager.hasChanges());
    
            // Subscribe with handler watching for EntityState changes
            this.addEntityStateChangeTracking(breezeEntityManager, this);
        }
    
        EntityManager.prototype.addEntityStateChangeTracking = function (bem, em) {
            if (this.entityStateTrackingToken != null) return;
            this.entityStateTrackingToken = bem.hasChangesChanged.subscribe(function (changeArgs) {
                em.hasChanges(changeArgs.hasChanges);
            });
        };
        return EntityManager;
    })();
    
    然后在viewModels上,显示EntityManager

    var ViewModel = (function (_super) {
        __extends(ViewModel, _super);
        function ViewModel(typeName) {
            _super.call(this);
            this.type = entities.getType(typeName);
        }
    
        ViewModel.prototype.loadEntity = function (id) {
            this.entityManager = new breeze.EntityManager("MyManager");;
        };
        return ViewModel;
    })(ViewModelBase);
    exports.ViewModel = ViewModel;
    
    然后在您的淘汰UI中:

    <button type="button" class="btn btn-info" data-i18n="common.save" data-bind="click: save, enable: entityManager.hasChanges">
    

    我们不愿意将此添加到propertyChangedEvent中。原则上,它是关于业务对象属性的更改,而不是实体基础结构属性的更改。我们还希望鼓励人们使用EntityManager.entityChange事件,它不太可能导致内存链接。网络:不太可能改变propertyChanged事件的行为。
    <button type="button" class="btn btn-info" data-i18n="common.save" data-bind="click: save, enable: entityManager.hasChanges">