मैं एक ही समस्या का सामना करना पड़ा, लेकिन मेरी यूज-केस में थोड़ा और अधिक मांग है: मैं दो की जरूरत है दोहराव के माध्यम से गहरी बाध्यकारी। इसके अलावा मैं प्रत्येक परिवर्तन पर पूरे पेड़ को फिर से लिखने का जोखिम नहीं उठा सकता।
चूंकि मुझे कोई समाधान नहीं मिला और बहुलक टीम धीरे-धीरे इस मुद्दे पर इसे लेती प्रतीत होती है, मैंने समय के लिए कुछ बनाया है। यह ES2015 में लिखा गया है, लेकिन वेनिला ES5 में अनुवाद करना सीधा होना चाहिए। वैसे भी क्रोम में चलता है। या इसे बेबल पर फेंक दें। This page विवरण कैसे। इस पोस्ट करने का उद्देश्य के लिए सार:
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>
उपयोग:
<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>
आशा है कि किसी को मदद मिलती है। अनुमानित बहुलक अब कल की तरह सुविधा प्राप्त करता है :-)
स्रोत
2016-05-03 22:05:39
धन्यवाद! मैं अभी भी एक छोटे संस्करण की उम्मीद कर रहा हूं ... Object.keys() का उपयोग आपके लूप के बजाय किया जा सकता है, लेकिन इससे यह बहुत छोटा नहीं होगा। – Tamas
मुझे यकीन नहीं है कि आप और भी कर सकते हैं। आप 'dom-repeat' में केवल' सरणी 'का उपयोग कर सकते हैं। मैंने एक ऐसे फ़ंक्शन का उपयोग करने का भी प्रयास किया जो एक सरणी लौटा लेकिन यह काम नहीं कर रहा था। –