幸运的是,整个问题和任何其他类似问题的解决方案都以Blaze 包的形式提供给 Meteor API ,这是使反应式模板成为可能的核心 Meteor 包。如果您查看链接的文档,Blaze 包提供了一长串函数,这些函数允许以编程方式创建、呈现和删除反应性和非反应性内容的各种解决方案。
为了解决上述问题,您需要做以下事情:
首先,预测需要为应用程序动态呈现的不同 HTML 块。在这种情况下,这些块将是<div>{{name}}</div>
and <div>{{age}}</div>
,但它们实际上可以是任何有效的 HTML(尽管它还不是公共 API 的一部分,但未来开发人员将有更多选择以更动态的方式定义此内容,如文档中所述)。您可以将它们放入小的模板定义中,如下所示:
<template name="nameDiv">
<div>{{name}}</div>
</template>
和
<template name="ageDiv">
<div>{{age}}</div>
</template>
其次,firstTemplate
需要更改模板的定义以包含可以以编程方式引用的 HTML 节点,如下所示:
<template name="firstTemplate">
<div></div>
</template>
然后,您需要为firstTemplate
模板定义逻辑,利用 Blaze 包提供的一些功能,即Blaze.With、Blaze.render和Blaze.remove(尽管您可以更改以下逻辑并利用Blaze.renderWithData函数;这完全取决于您对如何定义逻辑的个人偏好 - 为了解释起见,我在下面仅提供一种可能的解决方案)。
Template.firstTemplate.onRendered(function() {
var dataContext = Template.currentData();
var unrenderedView = Blaze.With(dataContext, function() {
// Define some logic to determine if name/age template should be rendered
// Return either Template.nameDiv or Template.ageDiv
});
var currentTemplate = Template.instance();
var renderedView = Blaze.render(unrenderedView, currentTemplate.firstNode);
currentTemplate.renderedView = renderedView;
});
Template.firstTemplate.onDestroyed(function() {
var renderedView = Template.instance().renderedView;
Blaze.remove(renderedView);
});
因此,我们在onRendered
您的模板函数中所做的firstTemplate
是动态确定我们想要呈现到页面上的哪些数据(在您的情况下是名称或年龄),并使用该Blaze.With()
函数创建该模板的未呈现视图使用firstTemplate
模板的数据上下文。然后,我们选择firstTemplate
我们希望动态生成的内容包含在其中的模板元素节点,并将这两个对象传递给Meteor.render()
函数,该函数将未渲染的视图渲染到页面上,指定的元素节点作为渲染内容的父节点。
如果您阅读该Blaze.render()
函数的详细信息,您将看到此渲染的内容将保持反应状态,直到使用该Blaze.remove()
函数删除渲染的视图,或者从 DOM 中删除指定的父节点。在上面的示例中,我将引用从调用中收到的渲染视图Blaze.render()
并将其直接保存在模板对象上。我这样做是为了当模板本身被销毁时,我可以在onDestroyed()
回调函数中手动删除渲染的视图,并确保它确实被销毁了。