【问题标题】:How can I detect a change to an entity's EntityState?如何检测实体的 EntityState 的更改?
【发布时间】:2014-04-04 12:51:43
【问题描述】:

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

订阅customer.entityAspect.propertyChanged 我几乎可以做到这一点。属性更改标志着EntityState 的潜在更改。我可以订阅该事件并让我的处理程序更新我已添加到我的客户实体的isChanged observable。然后我将“取消”按钮启用绑定到isChanged,我很高兴。

propertyChanged 事件仅在 数据属性 更改时引发,例如 customer.Name("New Co.");。当用户单击“删除”按钮时不会引发它。 “删除”触发customer.entityAspect.setDelete();,它不会触及数据属性;它只是更改了客户的EntityState

(1) 为什么更改客户的EntityState 不会提高propertyChanged 和 (2) 我如何监听EntityState 的更改以便控制“取消”按钮?

P.S.:我正在使用 Knockout。

P.P.S:这个问题的灵感来自之前的 SO 问题 "entityAspect.setDeleted doesn't fire the subscribed propertyChanged event"

【问题讨论】:

    标签: breeze


    【解决方案1】:

    EntityState 发生变化时,Breeze 不会引发propertyChanged,这是正确的。也许应该。我们会考虑的。

    Breeze 也没有单独的事件实体 - 没有entityStateChanged 事件 - 在EntityState 更改时通知您。我们已经考虑过好几次了。我们一直在谈论自己。

    有一个比专门的entityStateChanged 事件执行得更好的完美解决方案。现在你必须自己编写代码。

    诀窍是听EntityManager,而不是实体。您将在DocCode "Teach Tests" 示例中找到此解决方案的一个变体;在 entityTest.js 模块中查找“can control custom ko entityState property via entityManager.entityChanged”。

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

    1. 订阅entityManager.entityChanged事件;当它被提出并且原因是实体的EntityState 更改时,您更新该实体的isChanged boolean KO observable(如果该属性存在)。

    2. isChanged 可观察对象添加到应该以这种方式观察的实体类型。

    这是第 1 步的示例:监听状态变化

    // 订阅处理程序以观察 EntityState 的变化 addEntityStateChangeTracking(经理); 功能 addEntityStateChangeTracking(entityManager) { if (entityManager._entityStateChangeTrackingToken) { 返回; } // 已经在跟踪它 // 使用令牌记住更改跟踪订阅; // 将来可能会取消订阅该令牌 entityManager._entityStateChangeTrackingToken = entityManager.entityChanged.subscribe(entityChanged); var entityStateChangeAction = 微风.EntityAction.EntityStateChange; 功能实体改变(changeArgs){ if (changeArgs.entityAction === entityStateChangeAction) { var 实体 = changeArgs.entity; if (entity && entity.isChanged) { // 实体有 observable var isUnchanged = entity.entityAspect.entityState.isUnchanged(); entity.isChanged(!isUnchanged); } } } }

    让我们谈谈第 2 步:将 isChanged 可观察对象添加到类型中。您似乎已经解决了那个问题,但我不确定如何解决。也许将它添加到类型的最佳位置是在type's initializer 中,因此您可以确定该属性将在那里,无论实体是由查询创建还是具体化。这是一个例子:

    var store = manager.metadataStore; 功能客户初始化(实体){ var isUnchanged = entity.entityAspect.entityState.isUnchanged(); entity.isChanged = ko.observable(!isUnchanged); } store.registerEntityTypeCtor('Customer', null, customerInit);

    这一切似乎需要做很多工作。如果 Breeze 在 EntityState 更改时引发 propertyChanged 事件会更容易。我们将给予更多考虑……可能会有一些很好的反驳论点。同时,我认为您在这里看到的是最好的方法。

    【讨论】:

    • 我们不愿意将此添加到 propertyChangedEvent。原则上,它是关于业务对象属性的更改,而不是实体基础设施属性。我们还想鼓励人们使用不太可能导致内存链接的 EntityManager.entityChange 事件。它的网络:不太可能改变 propertyChanged 事件的行为。
    【解决方案2】:

    我们发现将微风实体管理器封装在我们自己的内部为我们提供了很好的灵活性,使这个挑战在公园里散步,尤其是在 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;
    })();
    

    然后在您的 viewModel 上,公开 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;
    

    然后在您的淘汰赛用户界面中:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多