【发布时间】:2020-04-02 12:17:10
【问题描述】:
我是 Meteor/Blaze 的新手,但这是我公司正在使用的。
我很难理解 Blaze 是如何决定渲染基于 ReactiveDict 的内容
TL;DR
我从父数组中的ReactiveDict 数组创建了一些子模板。当ReactiveDict 更改时,子模板中的数据不会刷新,我不明白为什么。
我可能对 Blaze 渲染有误解。你能帮帮我吗?
家长
父 Html 模板
<template name="parent">
{{#each child in getChildren}}
{{> childTemplate (childArgs child)}}
{{/each}}
</template>
父 Javascript
反应变量模板呈现来自 getChildren 助手的子模板,该助手仅检索 ReactiveDict。
// Child data object
const child = () => ({
id: uuid.v4(),
value: ""
});
// Create a reactive dictionary
Template.parent.onCreated(function() {
this.state = new ReactiveDict();
this.state.setDefault({ children: [child()] });
});
// Return the children from the reactive dictionary
Template.parent.helpers({
getChildren() {
return Template.instance().state.get('children');
}
});
子模板参数(来自 parent 模板)
父模板给子模板一些用于设置默认值和回调的数据。
每个都使用childArgs 函数进行实例化,该函数使用孩子的id 来设置正确的数据和回调。
单击add 按钮时,它会将一个子级添加到ReactiveDict 中的children 数组中。
单击delete 按钮时,它会从ReactiveDict 中的children 数组中删除子元素。
Template.parent.helpers({
// Set the children arguments: default values and callbacks
childArgs(child) {
const instance = Template.instance();
const state = instance.state;
const children = state.get('children');
return {
id: child.id,
// Default values
value: child.value,
// Just adding a child to the reactive variable using callback
onAddClick() {
const newChildren = [...children, child()];
state.set('children', newChildren);
},
// Just deleting the child in the reactive variable in the callback
onDeleteClick(childId) {
const childIndex = children.findIndex(child => child.id === childId);
children.splice(childIndex, 1);
state.set('children', children);
}
}
}
})
孩子
子 html 模板
模板显示来自父级和 2 个按钮的数据,add 和 delete。
<template name="child">
<div>{{value}}</div>
<button class="add_row" type="button">add</button>
<button class="delete_row" type="button">delete</button>
</template>
子 javascript(事件)
这里调用的两个函数是作为参数从父模板传递的回调。
// The two functions are callbacks passed as parameters to the child template
Template.child.events({
'click .add_row'(event, templateInstance) {
templateInstance.data.onAddClick();
},
'click .delete_row'(event, templateInstance) {
templateInstance.data.onDeleteClick(templateInstance.data.id);
},
问题
我的问题是当我删除一个孩子时(使用回调来设置ReactiveDict 就像onAddClick() 函数一样),我的数据没有正确呈现。
文本示例:
我像这样添加行。
child 1 | value 1
child 2 | value 2
child 3 | value 3
当我删除 child 2 时,我得到了这个:
child 1 | value 1
child 3 | value 2
我想要这个:
child 1 | value 1
child 3 | value 3
我在Template.child.onRendered() 函数中使用来自childArgs 的数据初始化child。
-
很好:删除
ReactiveDict中的child时调用getChildren()函数,并且我在变量中有正确的数据(ReactiveDict中的children)。 - 好:如果我有 3 个孩子并且我删除了一个,那么 parent 模板只会呈现 2 个孩子。
-
不好:但是子进程的
onRendered()从未被调用(子进程的onCreated()函数也没有)。这意味着为 child 模板显示的数据是错误的。
图片示例
我正在添加图片以帮助理解:
正确的html显示的 HTML 是正确的:我有 3 个孩子,我删除了第二个。在我的 HTML 中,我可以看到显示的两个孩子在其 div 中具有正确的 ID。然而显示的数据是错误的。
过时的数据我已经删除了第一张图片中的第二个孩子。显示的孩子应该是第一个和第三个。 在控制台日志中,我的数据是正确的。红色数据是第一位的。紫色是第三个。
但我们可以看到已删除孩子的数据已显示(asd 和asdasd)。删除标签时,我可以在日志中看到第二个孩子的 ID,尽管它不应该再存在了。第二个子 ID 为绿色。
我可能误会了什么。你能帮帮我吗?
【问题讨论】:
-
这个问题不完整,无法回答。我们基本上还需要
parent的html 部分,如果有child模板也是html 和js 代码。我真的很好奇你是如何调用onDeleteClick的,因为通常模板事件应该用于 ui 事件。 -
@Jankapunkt 这应该是所有需要的信息。不要犹豫,问您是否觉得缺少其他东西。
标签: javascript meteor meteor-blaze spacebars