【问题标题】:Breeze.js: how to transform a Breeze entity to a plain JSON objectBreeze.js:如何将 Breeze 实体转换为纯 JSON 对象
【发布时间】:2013-04-18 14:58:01
【问题描述】:

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

breeze.NamingConvention.camelCase.setAsDefault();

...

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

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

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

问题是如何将实体转换为 JSON,这样:

  1. 生成的对象反映了服务器端使用的命名约定。
  2. 该对象包含简单的属性,而不是剔除的可观察对象。
  3. 并且不包含微风内部使用的任何其他附加属性或函数。

我期待找到类似的东西:

var json = application.toJS();

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

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

更新:你会原谅我的可怕黑客攻击,但因为我很着急我所做的暂时解决了我的问题只是暴露了entityManagerunwrapEntities 内部函数。我还稍微更改了函数定义(只是为了排除烦人的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();

【问题讨论】:

    标签: asp.net-mvc knockout.js breeze


    【解决方案1】:

    这是个好主意!您能否将其添加到Breeze User Voice。公开 Breeze 实体的“展开”是很有意义的。

    只是一个小说明,您编写的解包“hack”可能在未来版本的 Breeze 中不起作用,因为我们目前正在重构其中的一些代码,但我会尝试公开一个“更干净”的版本作为微风 API 的一部分。

    【讨论】:

    • 我已经做到了,没错here。我将查看更改日志并重构我的代码,以防建议将其用于将来的版本。顺便说一句,你们用 Breeze 做得很棒,我已经用了几个星期了,我认为它绝对很棒。
    【解决方案2】:

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

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

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多