初始化新对象时会触发流星中的新模板吗?
When initialising new objects is triggering new templates in meteor?
我正在构建一个页面,该页面需要创建一个矩阵,其中的数字或行和列是反应性的(可以通过用户单击 "add rows" 等来更改。)
我使用了一个为每个单元格准备内容的函数,客户端:
function prepareCells(rows, columns){
let matrixContent = {};
...logics here...
return matrixContent;
}
在客户端中还有以下助手:
Template.matrix.helpers({
matrixContents(){
const instance = Template.instance();
let rows = instance.state.get("rows");
let columns = instance.state.get("columns");
return prepareCells(rows, columns);
},
最后在 html Blaze 页面中有如下内容:
{{#each row in matrixContents.rows}}
{{#each row.cell}}
{{> cellcontent}}
{{/each}}
{{/each}}
每当反应变量发生变化时,助手就会重新运行..但是"cellContent"模板的onCreated函数不会!例如,如果您添加一行,onCreated 仅 运行 次(其中 n 是当前列数),而函数 "prepareCells" 总是 return 一个新对象。在 onCreated 内部有一些必须执行的相关逻辑,以正确初始化 cellcontent 的反应变量。
Meteor 使用什么模式来决定何时创建或不创建新模板?我找到了一个解决方法,其中 cellcontent 的助手(内部模板)使用 currentData:
Template.cellcontent.helpers({
getFoo(){
let data = Template.currentData();
...logic with the "real" data inside the cellcontent
}
因为依赖于 reactiveDict 的 cellcontent 助手会发现意想不到的值,因为 reactiveDict 是在创建时启动的,并不总是 运行,例如:
Template.cellcontent.helpers({
getFoo(){
let template = Template.instance();
instance.state =....you get unexpected data here
}
是否有关于此行为的参考资料?
为了重新 运行 你的 onCreated
函数你需要 a) 添加一个 autorun
b) 将它绑定到一个反应源,所以该源触发自动 运行 最后 c) 传入一些数据以触发 auto运行.
鉴于您上面的示例,这可能如下所示:
Template.cellcontent.onCreated(function cellContentOnCreated() {
const instance = this;
instance.state = new ReactiveDict(); // to save the processed data
// a - autorun this instance on changing incoming data
instance.autorun(function autorun() {
// b - autobind to a reactive data source
// because Template.currentData() is in a reactive context
// autorun will automatically re-run if it changes
const data = Template.currentData();
const processedData = //... process your incoming data
instance.state.set('processedData', processedData);
});
});
Template.cellcontent.helpers({
getFoo(){
return Template.instance().state.get('processedData');
}
});
为了实现 c) 您需要将一些数据传递到您的单元格内容模板:
{{#each row in matrixContents.rows}}
{{#each row.cell}}
{{> cellcontent data=this}}
{{/each}}
{{/each}}
请注意,this
表示每个块中的当前元素,并且要求 row.cell
是单元格内容元素的数组。如果不是这种情况,您可以查看此结构并重新组织它,以便将单元格内容数据传递到 cellcontent
模板。
我正在构建一个页面,该页面需要创建一个矩阵,其中的数字或行和列是反应性的(可以通过用户单击 "add rows" 等来更改。)
我使用了一个为每个单元格准备内容的函数,客户端:
function prepareCells(rows, columns){
let matrixContent = {};
...logics here...
return matrixContent;
}
在客户端中还有以下助手:
Template.matrix.helpers({
matrixContents(){
const instance = Template.instance();
let rows = instance.state.get("rows");
let columns = instance.state.get("columns");
return prepareCells(rows, columns);
},
最后在 html Blaze 页面中有如下内容:
{{#each row in matrixContents.rows}}
{{#each row.cell}}
{{> cellcontent}}
{{/each}}
{{/each}}
每当反应变量发生变化时,助手就会重新运行..但是"cellContent"模板的onCreated函数不会!例如,如果您添加一行,onCreated 仅 运行 次(其中 n 是当前列数),而函数 "prepareCells" 总是 return 一个新对象。在 onCreated 内部有一些必须执行的相关逻辑,以正确初始化 cellcontent 的反应变量。
Meteor 使用什么模式来决定何时创建或不创建新模板?我找到了一个解决方法,其中 cellcontent 的助手(内部模板)使用 currentData:
Template.cellcontent.helpers({
getFoo(){
let data = Template.currentData();
...logic with the "real" data inside the cellcontent
}
因为依赖于 reactiveDict 的 cellcontent 助手会发现意想不到的值,因为 reactiveDict 是在创建时启动的,并不总是 运行,例如:
Template.cellcontent.helpers({
getFoo(){
let template = Template.instance();
instance.state =....you get unexpected data here
}
是否有关于此行为的参考资料?
为了重新 运行 你的 onCreated
函数你需要 a) 添加一个 autorun
b) 将它绑定到一个反应源,所以该源触发自动 运行 最后 c) 传入一些数据以触发 auto运行.
鉴于您上面的示例,这可能如下所示:
Template.cellcontent.onCreated(function cellContentOnCreated() {
const instance = this;
instance.state = new ReactiveDict(); // to save the processed data
// a - autorun this instance on changing incoming data
instance.autorun(function autorun() {
// b - autobind to a reactive data source
// because Template.currentData() is in a reactive context
// autorun will automatically re-run if it changes
const data = Template.currentData();
const processedData = //... process your incoming data
instance.state.set('processedData', processedData);
});
});
Template.cellcontent.helpers({
getFoo(){
return Template.instance().state.get('processedData');
}
});
为了实现 c) 您需要将一些数据传递到您的单元格内容模板:
{{#each row in matrixContents.rows}}
{{#each row.cell}}
{{> cellcontent data=this}}
{{/each}}
{{/each}}
请注意,this
表示每个块中的当前元素,并且要求 row.cell
是单元格内容元素的数组。如果不是这种情况,您可以查看此结构并重新组织它,以便将单元格内容数据传递到 cellcontent
模板。