2

我有一个使用来自服务器的元数据创建的实体实例:

breeze.NamingConvention.camelCase.setAsDefault();

...

var applicationType = metadataStore.getEntityType('Application');
var application = applicationType.createEntity();

此特定模型中的所有对象都没有循环依赖关系。

在用户对相应对象进行了一些更改后,我需要对该实体执行一些自定义验证,因此我需要将该对象转换回其 JSON 简单形式并将其发送回验证控制器(ASP.NET MVC4) .

问题是如何将实体转换为 JSON,以便:

  1. 结果对象反映了服务器端使用的命名约定。
  2. 该对象包含简单的属性,而不是淘汰 observables。
  3. 并且不包含微风内部使用的任何其他附加属性或功能。

我期待找到类似的东西:

var json = application.toJS();

但是这样的方法是不存在的。使用 ko.toJS(application) 也不起作用,因为 (1)、(2) 和 (3) 没有实现。

我确信这应该很容易做到,但我什至在文档中找不到任何与远程相关的东西。

更新:你会原谅我可怕的黑客攻击,但因为我很着急我所做的暂时解决了我的问题,只是暴露unwrapEntitiesentityManager. 我还稍微更改了函数定义(只是为了排除那个烦人的entityAspect):

function unwrapEntities(entities, metadataStore, includeEntityAspect) {
    var rawEntities = entities.map(function(e) {
        var rawEntity = unwrapInstance(e);

        if (includeEntityAspect !== undefined && includeEntityAspect === false) {
            return rawEntity;
        }
        ...
    });
}

而且因为我的entityManager服务中随时都有可用的数据,所以我能够扩展我的类型定义以执行以下操作:

function createApplicant(initialValues) {
    var applicant = applicantType.createEntity(initialValues);

    applicant.toJS = function () {
        var unwrappedEntities = entityManager.unwrapEntities([applicant], entityManager.metadataStore, false);
        return unwrappedEntities[0];
    };

    return applicant;
}

这正是我所需要的:

var json = application.toJS();
4

2 回答 2

3

这是一个好主意!您能否将其添加到微风用户语音中。公开 Breeze 实体的“展开”是很有意义的。

只是一个小旁注,您编写的展开“hack”可能无法在未来版本的 Breeze 中工作,因为我们目前正在重构其中的一些代码,但我会尝试公开一个“更干净”的版本作为微风 API。

于 2013-04-25T01:28:08.833 回答
0

这可能是过时的解决方案,但我在我的 typescript 类中做了一些 hack 以在没有微风核心的帮助的情况下做到这一点。我做了这个 hack,因为我的微风版本和输入文件不包括 unwrap 方法,我现在不想升级它。
另一个好处是结果类绝对没有任何未包含在元数据中的额外属性,并且您可以控制是否只需要普通实体或者是否希望将相关实体也嵌入结果中。

只需将此代码包含在您的打字稿类中即可完成此操作:

public unwrapEntity(entity: breeze.Entity, includeRefs: boolean): any {
    var refs = [];
    return this.unwrapEntityInner(entity, refs, includeRefs);
}

private objInArray(obj: any, refs: Array<any>): boolean {
    var ret = false;
    for (var i = 0; i < refs.length; i++) {
        if (obj === refs[i]) {
            ret = true;
            break;
        }
    }
    if (!ret)
        refs.push(obj);
    return ret;
}

private unwrapEntityInner(entity: breeze.Entity, refs: Array<any>, includeRefs: boolean): any {
    var data = {};
    for (var prop in entity) {
        if (entity.hasOwnProperty(prop) && ko.isObservable(entity[prop])) {
            data[prop] = entity[prop]();
            if (typeof data[prop] !== 'undefined' && data[prop] != null) {
                if (typeof data[prop].entityAspect !== 'undefined') {
                    data[prop] = (includeRefs && !this.objInArray(data[prop], refs)) ? this.unwrapEntityInner(data[prop], refs, includeRefs ) : null;
                }
                else if ($.isArray(data[prop])) {
                    if (!includeRefs || this.objInArray(data[prop], refs))
                        data[prop] = [];
                    else {
                        var tmp = data[prop];
                        data[prop] = [];
                        for (var i = 0; i < tmp.length; i++) {
                            data[prop].push(this.unwrapEntityInner(tmp[i], refs, includeRefs));
                        }
                    }
                }
            }
        }
    }
    return data;
}
于 2016-07-31T15:39:58.973 回答