Templates 如何在Polymer 1.0中对对象而不是数组使用dom repeat?

Templates 如何在Polymer 1.0中对对象而不是数组使用dom repeat?,templates,polymer,polymer-1.0,Templates,Polymer,Polymer 1.0,迭代数组myarray=[1,2,3]的工作原理如下: <template is="dom-repeat" items="[[myarray]]"> <span>[[item]]</span> </template> [[项目]] 如何迭代对象myobject={a:1,b:2,c:3}?您需要将此对象转换为一个有意义的数组,以便能够使用dom repeat对其进行迭代 <link rel="import" href="bowe

迭代数组
myarray=[1,2,3]
的工作原理如下:

<template is="dom-repeat" items="[[myarray]]">
    <span>[[item]]</span>
</template>

[[项目]]

如何迭代对象
myobject={a:1,b:2,c:3}

您需要将此对象转换为一个有意义的数组,以便能够使用
dom repeat
对其进行迭代

<link rel="import" href="bower_components/polymer/polymer.html">

<dom-module id="test-element">
    <style>
    </style>
    <template>
        <template is="dom-repeat" items="{{myObjAsArray}}">
            name: <span>{{item.name}}</span>
            value: <span>{{item.value}}</span>
        </template>
    </template>
</dom-module>

<script>
    Polymer({
        is: "test-element",
        properties: {
            myObj: {
                type: Object,
                value: function () {
                    return {
                        a: 1,
                        b: 2,
                        c: 3
                    };
                }
            },
            myObjAsArray: {
                type: Array,
                value: function () {
                    return [];
                }
            }
        },
        attached: function () {
            var propArray = [];
            for (var prop in this.myObj) {
                if (this.myObj.hasOwnProperty(prop)) {
                    propArray.push({name: prop, value: this.myObj[prop]});
                }
            }

            this.myObjAsArray = propArray;
        }
    });
</script>
我已经用初始值创建了一个
myObj
属性。然后,我创建了一个名为
myObjAsArray
的属性,它是一个空数组。在本地dom就绪时调用的
ready
回调函数中,我迭代了
myObj
的所有属性,并将它们添加到
myObjAsArray
(请参阅如何迭代对象属性)。然后,您可以使用
dom repeat
对该数组进行迭代

<link rel="import" href="bower_components/polymer/polymer.html">

<dom-module id="test-element">
    <style>
    </style>
    <template>
        <template is="dom-repeat" items="{{myObjAsArray}}">
            name: <span>{{item.name}}</span>
            value: <span>{{item.value}}</span>
        </template>
    </template>
</dom-module>

<script>
    Polymer({
        is: "test-element",
        properties: {
            myObj: {
                type: Object,
                value: function () {
                    return {
                        a: 1,
                        b: 2,
                        c: 3
                    };
                }
            },
            myObjAsArray: {
                type: Array,
                value: function () {
                    return [];
                }
            }
        },
        attached: function () {
            var propArray = [];
            for (var prop in this.myObj) {
                if (this.myObj.hasOwnProperty(prop)) {
                    propArray.push({name: prop, value: this.myObj[prop]});
                }
            }

            this.myObjAsArray = propArray;
        }
    });
</script>

名称:{{item.name}
值:{{item.value}}
聚合物({
是:“测试元素”,
特性:{
myObj:{
类型:对象,
值:函数(){
返回{
答:1,,
b:2,
c:3
};
}
},
myObjAsArray:{
类型:数组,
值:函数(){
返回[];
}
}
},
附:函数(){
var propArray=[];
for(此.myObj中的var prop){
if(this.myObj.hasOwnProperty(prop)){
push({name:prop,value:this.myObj[prop]});
}
}
this.myObjAsArray=propArray;
}
});

我一直在使用
Object.keys(obj).map(函数(prop){return{id:prop,val:obj[prop]})
下面是一个完整的实现:

<test-element obj='{"a": 1, "b": 2, "c": 3}'></test-element>

<dom-module id="test-element">
    <template>

        <template is="dom-repeat" items="{{_toArray(obj)}}">
            name: <span>{{item.name}}</span>
            <br> value: <span>{{item.value}}</span>
            <br>
            <hr>
        </template>

    </template>
    <script>
    Polymer({

        properties: {
            obj: Object
        },

        _toArray: function(obj) {
            return Object.keys(obj).map(function(key) {
                return {
                    name: key,
                    value: obj[key]
                };
            });
        }

    });
    </script>

</dom-module>

名称:{{item.name}

值:{{item.value}}

聚合物({ 特性:{ 对象:对象 }, _toArray:功能(obj){ 返回Object.keys(obj).map(函数(键){ 返回{ 姓名:key,, 值:obj[键] }; }); } });
我面临同样的问题,但我的用例要求更高:我需要通过重复进行双向深度绑定。另外,我不能在每次更改时重写整棵树

由于我没有找到解决方案,聚合物团队似乎在这个问题上采取了缓慢的行动,所以我暂时做了一些事情。它是在ES2015中编写的,但将其转换为普通ES5应该很简单。在Chrome中运行。或者把它扔给巴布尔。详细说明如何。这篇文章的主旨是:

vulcanize element.html --inline-script --inline-css | \
    crisper -h element.v.html -j element.js;
babel element.js -o element.js
现在我们开始:

<link rel="import" href="../../bower_components/polymer/polymer.html">

<dom-module id="my-objarray">
    <script>
(function() {
    'use strict';

    class Objarray {
        beforeRegister() {
            this.is = 'my-objarray';
            this.properties = {
                array:{
                    notify:true,
                    type:Array,
                    value:function() {return new Array();}
                },
                object:{
                    notify:true,
                    type:Object
                }
            };
            this.observers = ['_onArray(array.*)', '_onObject(object.*)'];
        }
        _onObject(change) {
            if(this._setting) return;
            if(change.path == "object") this._rewriteArray();
            else this._writeElement(change);
        }

        _rewriteArray() {
            this.splice("array", 0, this.array.length);
            for(let i in this.object) {
                this.push("array", {key:i, value:this.object[i]});
            }
        }

        _writeElement(change) {
            const path = change.path.match(/^object\.([^\.]+)(.*)$/);
            const key = path[1];
            const objectPath = "object." + key + (path[2] || "");
            const id = this._getId(key);
            const arrayPath = "array." + id + ".value" + (path[2] || "");
            this.set(arrayPath, this.get(objectPath));
        }

        _getId(key) {
            const collection = Polymer.Collection.get(this.array);
            for(const element of this.array) {
                if((element && element.key) === key) {
                    return collection.getKey(element);
                }
            }
        }

        _onArray(change) {
            let path = change.path.match(/^array\.(#\d+)\.([^\.]+)(\.|$)/);
            if(!path) return;
            let id = path[1], field = path[2];
            if(field == "key") throw new Error("my-objarray: Must not change key!");
            if(field != "value") throw new Error("my-objarray: Only change inside value!");
            this._setting = true;
            this.set(this._getPath(change, id), change.value);
            delete this._setting;
        }

        _getPath(change, id) {
            let collection = Polymer.Collection.get(change.base);
            let index = change.base.indexOf(collection.getItem(id));
            let key = change.base[index].key;
            return change.path.replace("array." + id + ".value", "object." + key);
        }

    }

    Polymer(Objarray);
})();
    </script>
</dom-module>

(功能(){
"严格使用",;
类Objarray{
注册前{
this.is='my objarray';
此属性={
数组:{
通知:正确,
类型:数组,
值:函数(){返回新数组();}
},
对象:{
通知:正确,
类型:对象
}
};
this.observators=[''u onArray(array.*'),'u onObject(object.*');
}
_onObject(更改){
如果(此._设置)返回;
如果(change.path==“object”),则重写此数组();
否则,将写入元素(更改);
}
_重写数组(){
this.splice(“array”,0,this.array.length);
for(让我输入这个.object){
push(“数组”{key:i,value:this.object[i]});
}
}
_writeElement(更改){
const path=change.path.match(/^object\([^\.]+)(.*)$/);
常量键=路径[1];
const objectPath=“object.”+key+(路径[2]| |“”);
const id=this.\u getId(key);
const arrayPath=“array.+id+”.value“+(路径[2]| |“”);
set(arrayPath,this.get(objectPath));
}
_getId(键){
const collection=Polymer.collection.get(this.array);
for(此.array的常量元素){
if((element&&element.key)==key){
返回集合.getKey(元素);
}
}
}
_onArray(更改){
让path=change.path.match(/^array\(#\d+)([^\.]+)(\.\124;$)/;
如果(!path)返回;
设id=path[1],field=path[2];
if(field==“key”)抛出新错误(“my objarray:不得更改key!”);
如果(field!=“value”)抛出新错误(“my objarray:仅更改内部值!”);
此。_设置=真;
this.set(this.\u getPath(change,id),change.value);
删除此设置。\u;
}
_getPath(更改,id){
让collection=Polymer.collection.get(change.base);
让index=change.base.indexOf(collection.getItem(id));
让key=change.base[index].key;
返回change.path.replace(“数组”+id+“.value”、“对象”+key);
}
}
聚合物(Objarray);
})();
用法:

<dom-module id="my-objarray-test">
    <template strip-whitespace>
        <my-objarray object="{{items}}" array="{{array}}"></my-objarray>
        <template is="dom-repeat" items="{{array}}">
            <div>
                <label>{{item.key}}:</label>
                <input type="number" value="{{item.value.data::input}}">
            </div>
        </template>
    </template>
    <script>
(function() {
    'use strict';

    class ObjarrayTest {
        beforeRegister() {
            this.is = 'my-repeat-test';
            this.properties = {
                items:{
                    notify:true,
                    type:Object,
                    value:function() {return new Object();}
                }
            };
            this.observers = ['_onItems(items.*)'];
        }

        ready() {
            console.log("my-repeat-test.ready");
            this.items = {a:{data:1}, b:{data:2}};
        }

        _onItems(change) {console.log("test._onItems", change.path);}

    }

    Polymer(ObjarrayTest);
})();
    </script>
</dom-module>

{{item.key}}:
(功能(){
"严格使用",;
类ObjarrayTest{
注册前{
this.is=‘我的重复测试’;
此属性={
项目:{
通知:正确,
类型:对象,
值:函数(){返回新对象();}
}
};
这一点。观察员=[''项目*';
}
就绪(){
控制台
<template is="dom-repeat" items="[[_toArray(obj)]]">
  key: [[item.key]] val: [[item.val]]
</template>
_toArray: function(obj, deep) {
  var array = [];
  for (var key in obj) {
    if (deep || obj.hasOwnProperty(key)) {
      array.push({
        key: key,
        val: obj[key]
      });
    }
  }
  return array;
}