是否有一个通用的引擎可以将 JavaScript 对象翻译成不同的对象?

Is there a versatile engine to translate JavaScript object into a different object?

我正在寻找一种使用模板将大对象转换为自定义对象的通用方法。它应该能够遍历数组的each值,并在循环中引用父值。

想象一个像这样的对象:

{
    collectionId : 432,
    products : [
        {
            productId : 1155,
            suppliers : [
                {
                    supplierId : 252,
                    supplier : 'SupplyCompany',
                    shipments : [
                        {
                            date : 'foo',
                            order : 'bar',
                            id : 45
                        },
                        {},
                        {},
                        //...
                    ]
                },
                {},
                {},
                //...
            ]
        },
        {},
        {},
        //...
    ],
}

例如,我想将其扁平化为:

[
    {
        collectionId : 432,
        productId : 1155,
        supplierId : 252,
        supplier : 'SupplyCompany',
        date : 'foo',
        order : 'bar',
        id : 45
    },
    {},
    {},
    //...
]

现在我正在使用手动 for for for 循环,但是当源对象更改或我的输出对象之一更改时,这不是很通用。 'hardcode' 这些翻译不是很容易维护。

有一些模板引擎可以做一些类似于我想要的事情,例如JsRender。它理论上允许你做我需要的事情:

{{for products}}
    {{for suppliers}}
        {{for shipments}}
            collectionId : {{:#parent.parent.parent.parent.data.collectionId}}
            productId : {{:#parent.parent.parent.data.productId}},
            supplierId : {{:#parent.parent.data.supplierId}},
            supplier : {{:#parent.parent.data.supplier}},
            date : {{:date}},
            order : {{:order}},
            id : {{:id}
        {{/for}}
    {{/for}}
{{/for}}

(这很好,因为 Mustache 不允许你这样做。)

然而,jsRender 读取字符串(模板)并输出字符串(html)。所有 stringifyparse 的开销对我来说没有任何好处。

我正在寻找可以对对象进行这种处理的东西。从对象到对象。

有几种方法可以使用 JsRender 完成此类操作。例如,创建自定义标签、转换器等(或使用辅助函数)并使它们具有将对象映射到某些输出对象的副作用真的很容易。当然 JsRender 的理念通常是声明式的,没有副作用,但如果你愿意,你确实可以使用它 'processor'.

这里有一个 jsfiddle sample 可以给你一些想法:

它使用自定义标签:

$.views.tags({
  addObject: function(target) {
    var item = $.extend({}, this.tagCtx.props);
    target.push(item);
    ...
  }
})

和模板:

{{for products ~collectionId=collectionId}}
    {{for suppliers ~productId=productId}}
        {{for shipments ~supplierId=supplierId ~supplier=supplier}}
            {{addObject ~target collectionId=~collectionId productId=~productId supplierId=~supplierId supplier=~supplier date=date order=order id=id/}}
        {{/for}}
    {{/for}}
{{/for}}