我正在为孩子们写一个定制的Blaze块助手:
<template name="parent"> {{> Template.contentBlock ..}} </template> <template name="child"> {{> Template.contentBlock ..}} </template>
我的预期用例是拥有一个带有任意子节点的模板,我在html文件中定义.
{{#parent}} {{#child id="child1" title="Child 1"}} <p>This is content of child 1</p> {{/child}} {{#child id="child2" title="Child 2"}} <p>This is content of child 2</p> {{/child}} {{#child id="childN" title="Child N"}} <p>This is content of child N</p> {{/child}} {{/parent}}
到目前为止没问题.但是,在父模板的onCreated / autorun中,我希望能够访问子模板.我想使用这些数据在父模板元素中动态创建
Template.parent.onCreated(function () { const instance = this; instance.state = new ReactiveDict(); instance.autorun(function () { const contentBlocks = // how? instance.state.set("children",contentBlocks); }); }); Template.parent.helpers({ children() { return Template.instance().state.get("children"); } });
子项将在父模板中使用如下:
{{#parent}} {{#each children}} do something with {{this.value}} {{/each}} {{#child id="child1" title="Child 1"}} <p>This is content of child 1</p> {{/child}} {{#child id="child2" title="Child 2"}} <p>This is content of child 2</p> {{/child}} {{#child id="childN" title="Child N"}} <p>This is content of child N</p> {{/child}} {{/parent}}
我不想要的是访问contentBlock的内容(< p>),而是获取添加的子模板的列表.
这可能与当前的Template / Blaze API有关吗? documentation在这一点上有点薄.
这基本上与这篇文章相反:How to get the parent template instance (of the current template)
编辑1:使用父视图的渲染功能(仅部分工作)
我找到了一种方法来获取父模板的子项,但不是他们的数据反应性:
// in Template.parant.onCreated -> autorun const children = instance.view.templateContentBlock.renderFunction() .filter(child => typeof child === 'object') .map(el => Blaze.getData(el._render())); console.log(children); // null,null,null because Blaze.getData(view) does return null
我找到的另一种方法是使用共享的ReactiveVar,但在我看来都不够干净.我只想在父js代码中获取Template实例列表.
编辑2:使用共享的ReactiveVar(仅部分工作)
只要它在两个模板的范围内,就可以使用共享的ReactiveVar:
const _cache = new ReactiveVar({}); Template.parent.onCreated(function () { const instance = this; instance.state = new ReactiveDict(); instance.autorun(function () { const children = Object.values(_cache.get()); instance.state.set("children",children); }); }); Template.parent.helpers({ children() { return Template.instance().state.get("children"); } });
工作(但只渲染一次,不反应):
Template.child.onCreated(function () { const instance = this; const data = Template.currentData(); const cache = _cache.get(); cache[data.id] = data; _cache.set(cache); });
不工作(子自动运行是设置值,但不呈现新值):
Template.child.onCreated(function () { const instance = this; instance.autorun(function() { const instance = this; const data = Template.currentData(); const cache = _cache.get(); cache[data.id] = data; _cache.set(cache); }); });
解决方法
这是我想出来的.请告诉我这是你想要的还是我误解了.
main.html中:
<body> {{> content}} </body> <template name="content"> {{#parent}} {{#each children}} <p>do something with {{this.id}}</p> <p>data: {{this.tmpl.data.title}}</p> {{/each}} {{#child id="child1" title="Child 1" parentTemplate=this.parentTemplate}} <p>This is content of child 1</p> {{/child}} {{#child id="child2" title="Child 2" parentTemplate=this.parentTemplate }} <p>This is content of child 2</p> {{/child}} {{#child id="childN" title="Child N" parentTemplate=this.parentTemplate }} <p>This is content of child N</p> {{/child}} {{/parent}} </template> <template name="parent"> {{> Template.contentBlock parentTemplate=template}} </template> <template name="child"> {{> Template.contentBlock }} </template>
main.js
import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import './main.html'; Template.content.helpers({ children() { return this.parentTemplate.children.get(); },}); Template.parent.onCreated(function () { this.children = new ReactiveVar([]); }); Template.parent.helpers({ template() { return Template.instance(); } }); Template.child.onRendered(function () { const children = this.data.parentTemplate.children.get(); children.push({ id: this.data.id,tmpl: this }); this.data.parentTemplate.children.set(children); });
输出: