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">