Meteor(Blaze)の反応依存ツリーで作業していますが、これを実行する最良の方法が見つかりませんでした。Meteor:オブジェクト属性の親子依存テンプレートを取得する
まず、私は属性elements
(配列)を持つitem
オブジェクトを、設定した容器を持っている。この例では問題
。
elements
属性はループであり、そのインスタンスごとに子テンプレートがロードされます。
要素は子テンプレートで更新できますが、更新はコンテナに伝播されません。
さらに、からitem
ReactiveVarを更新するためにAdd
ボタンを追加しました。 item
がコンテナで更新された後、各フィールドのレンダリングが更新されるため、オブジェクトは更新されましたが再レンダリングされません。
HTML
<template name="container">
{{#let item=getItem}}
<h1>Update {{item._id}}</h1>
{{#each element in item.elements}}
<div>
{{> elementForm element}}
<small>{{element.name}}</small>
</div>
{{/each}}
{{/let}}
<button name="add">Add</button>
</template>
<template name="elementForm">
{{#let el=getEl}}
<input value="{{el.name}}"/>
{{/let}}
</template>
親テンプレート
Template.container.onCreated(function onContainerCreated() {
// From data
let item = {
_id: '123abc',
elements: [
{name: "El #1"},
{name: "El #2"},
{name: "El #3"},
]
}
// Create master ReactiveVar
this.item = new ReactiveVar(item);
});
Template.container.helpers({
getItem() {
return Template.instance().item.get();
},
});
Template.container.events({
// Add a new element (Will refresh all elements render)
'click button[name="add"]'(e) {
let instance = Template.instance()
let item = instance.item.get()
item.elements.push({name: "new El"})
instance.item.set(item)
},
})
子テンプレート
/* Element */
Template.elementForm.onCreated(function onElementCreated() {
this.el = new ReactiveVar(this.data)
});
Template.elementForm.helpers({
getEl() {
return Template.instance().el.get()
}
})
Template.elementForm.events({
'change input'(e) {
let instance = Template.instance()
let el = instance.el.get()
el.name = e.currentTarget.value
instance.el.set(el)
}
})
プレビュー
流星が埋め込みコードに統合できないため、いくつかの画像を作成します。
デフォルトページ
更新入力は、コンテナが再すべてのコンテナをレンダリングし、新しい値
を取得する、新しいアイテムを追加します。をレンダリングに影響しませんでした
解決策1?は、私が子供に全体ReactiveVarを送信することは、子供に.set()
メソッドを使用するための解決策になることができるよりも知っている子
にitem
ReactiveVarを送信します。
しかし、私はこのハックを使用している場合、私は(最高ではない)各elementForm
に全体item
を送信する必要があります
Exemple
/* Html */
<Template name="parentTemplate">
<small>{{getFoo}}</small>
{{> childTemplate getItem}}
</Template>
<Template name="childTemplate">
<input value="{{getFoo}}" />
</Template>
/* Parent */
Template.parentTemplate.onCreated(function onParentCreated() {
this.item = new ReactiveVar({ foo: bar})
});
Template.parentTemplate.helpers({
getFoo() {
return Template.instance().item.get().foo
},
getItem() {
return Template.instance().item // Send reactive var, net value (.get)
}
})
/* Child */
Template.childTemplate.onCreated(function onChildCreated() {
this.item = this.data.item // Use Parent Reactive var
});
Template.childTemplate.helpers({
getFoo() {
return Template.instance().item.get().foo
},
})
Template.childTemplate.events({
'change input'(e) {
let item = Template.instance().item.get()
item.foo = e.currentTarget.value
Template.instance().item.set(item) // Will update parent
},
})
ソリューション2?コールバック
他の解決策は、要素テンプレートのデータに加えて、親テンプレートに特定の要素のマスターReactiveVarを更新するよう通知するために、各アクション(変更など)のコールバックを子テンプレートに送信することです。
例
/* Html */
<Template name="parentTemplate">
<small>{{getFoo}}</small>
{{> childTemplate getData}}
</Template>
<Template name="childTemplate">
<input value="{{getFoo}}" />
</Template>
/* Parent */
Template.parentTemplate.onCreated(function onParentCreated() {
this.item = new ReactiveVar({ foo: bar})
});
Template.parentTemplate.helpers({
getFoo() {
return Template.instance().item.get().foo
},
getData() {
let instance = Template.instance()
return {
item: instance.item.get(),
onChange: function(val) {
// Update item here
let item = instance.item.get()
item.foo = val
instance.item.set(item)
}
}
}
})
/* Child */
Template.childTemplate.onCreated(function onChildCreated() {
});
Template.childTemplate.helpers({
getFoo() {
return Template.instance().data.item.foo
},
})
Template.childTemplate.events({
'change input'(e) {
// Call parent callback
Template.instance().data.onChange(e.currentTarget.value)
},
})
最後の質問
項目オブジェクトから要素のリストを処理するために、親/子テンプレートを処理するための最良の方法は何ですか?
あなたは 'ReactiveVar'を持っていなくても、' container'の 'item'を更新しますか?子テンプレートに作成しますか? – Arthur
なぜアイテムをreactVarにラップしますか?あなたが更新したい唯一のものは要素のデータです。ですから、ある意味では、あなたの親にReactVarによって各子供の価値に応じた時間を持たせることになります。 –
ハム大丈夫!私はすべての要素が現在ReactiveVarである部分を見逃していました。うまくいきましたが、 'item'オブジェクト(私の場合はmongodbオブジェクトで' meteor-astronomy'パッケージを使用しています)は子供のtempalteに対して行われた更新についての情報を持っていません。私は、リアクティブオブジェクト(そして単一のvarだけではない)の場合、強烈な親子テンプレートのコールバックを使用すると思います。 – Arthur