breeze:在客户端模型中创建继承

时间:2014-05-02 08:19:05

标签: breeze

我在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功能。这不可能吗?

1 个答案:

答案 0 :(得分:2)

我们的错误

让我们从Breeze“backingStore”模型库适配器中最近发现的 Breeze bug 开始。

该适配器的一部分负责重写实体构造函数的数据属性,以便它们变为可观察和自我验证,并在注册具有registerEntityTypeCtor的类型时启动。

它试图跟踪它已重写的属性。错误是它记录了EntityType上的重写事实而不是构造函数。因此,每次注册新类型时,都没有意识到它已经重写了基类Job类型的属性并重新包装了该属性。

这发生在你身上。您注册的每个派生类型都重新包装/重写了基类型(及其基类型等)的属性。

在您的示例中,如果您注册了三个子类型,则基类Job属性将被重写3次,其内部逻辑将执行3次。当你停止注册子类型的构造函数时,问题就消失了。

我们正在开发一个修改过的Breeze“backingStore”模型库适配器,它不会出现这个问题,巧合的是,它会在测试场景中表现得更好(这就是我们首先发现错误的方法)。

你的坏?

哇,你有一些毛茸茸的代码。为什么这么复杂?特别是,为什么要将一次性MetadataStore配置添加到实体构造函数的原型中?

我一定错过了什么。注册类型的代码通常更小更简单。我得到你想要将每种类型放在自己的文件中并让它自行注册。它的成本(正如你所写的那样)是巨大的体积和复杂性。请重新考虑你的方法。看看其他Breeze样本,例如Zza-Node-Mongo。

感谢您报告此问题。和我们一起住在那里。修复应该很快到来......我希望在下一个版本中。