我在configureMetadataStore上遇到了一个奇怪的问题。
我的模特:
class SourceMaterial {
List<Job> Jobs {get; set;}
}
class Job {
public SourceMaterial SourceMaterial {get; set;}
}
class JobEditing : Job {}
class JobTranslation: Job {}
用于配置作业实体的模块:
angular.module('cdt.request.model').factory('jobModel', ['breeze', 'dataService', 'entityService', modelFunc]);
function modelFunc(breeze, dataService, entityService) {
function Ctor() {
}
Ctor.extend = function (modelCtor) {
modelCtor.prototype = new Ctor();
modelCtor.prototype.constructor = modelCtor;
};
Ctor.prototype._configureMetadataStore = _configureMetadataStore;
return Ctor;
// constructor
function jobCtor() {
this.isScreenDeleted = null;
}
function _configureMetadataStore(entityName, metadataStore) {
metadataStore.registerEntityTypeCtor(entityName, jobCtor, jobInitializer);
}
function jobInitializer(job) { /* do stuff here */ }
}
用于配置JobEditing实体的模块:
angular.module('cdt.request.model').factory(jobEditingModel, ['jobModel', modelFunc]);
function modelFunc(jobModel) {
function Ctor() {
this.configureMetadataStore = configureMetadataStore;
}
jobModel.extend(Ctor);
return Ctor;
function configureMetadataStore(metadataStore) {
return this._configureMetadataStore('JobEditing', metadataStore)
}
}
用于配置JobTranslation实体的模块:
angular.module('cdt.request.model').factory(jobTranslationModel, ['jobModel', modelFunc]);
function modelFunc(jobModel) {
function Ctor() {
this.configureMetadataStore = configureMetadataStore;
}
jobModel.extend(Ctor);
return Ctor;
function configureMetadataStore(metadataStore) {
return this._configureMetadataStore('JobTranslation', metadataStore)
}
}
然后模型配置如下:
JobEditingModel.configureMetadataStore(dataService.manager.metadataStore);
JobTranslationModel.configureMetadataStore(dataService.manager.metadataStore);
现在,当我为JobEditing调用createEntity时,将创建实例,并且在某些时候,breeze调用setNpValue
并将新创建的Job添加到np SourceMaterial。
这一切都很好,除了它被添加两次!
调用rawAccessorFn(newValue);
时会发生这种情况。 实际上它被称为两次。
如果我添加一种新类型的作业(因此我使用metadataStore注册一个新类型),那么新的作业将被添加三次到np。
我无法看清我做错了什么。有人可以帮忙吗?
修改
我注意到如果我改变了:
metadataStore.registerEntityTypeCtor(entityName, jobCtor, jobInitializer);
到
metadataStore.registerEntityTypeCtor(entityName, null, jobInitializer);
然后一切正常!所以问题是注册相同的jobCtor功能。这不可能吗?
答案 0 :(得分:2)
让我们从Breeze“backingStore”模型库适配器中最近发现的 Breeze bug 开始。
该适配器的一部分负责重写实体构造函数的数据属性,以便它们变为可观察和自我验证,并在注册具有registerEntityTypeCtor
的类型时启动。
它试图跟踪它已重写的属性。错误是它记录了EntityType上的重写事实而不是构造函数。因此,每次注册新类型时,都没有意识到它已经重写了基类Job
类型的属性并重新包装了该属性。
这发生在你身上。您注册的每个派生类型都重新包装/重写了基类型(及其基类型等)的属性。
在您的示例中,如果您注册了三个子类型,则基类Job
属性将被重写3次,其内部逻辑将执行3次。当你停止注册子类型的构造函数时,问题就消失了。
我们正在开发一个修改过的Breeze“backingStore”模型库适配器,它不会出现这个问题,巧合的是,它会在测试场景中表现得更好(这就是我们首先发现错误的方法)。
我一定错过了什么。注册类型的代码通常更小更简单。我得到你想要将每种类型放在自己的文件中并让它自行注册。它的成本(正如你所写的那样)是巨大的体积和复杂性。请重新考虑你的方法。看看其他Breeze样本,例如Zza-Node-Mongo。
感谢您报告此问题。和我们一起住在那里。修复应该很快到来......我希望在下一个版本中。