了解 Blaze

虽然 Blaze 是一款非常直观的渲染系统,但它确实有一些怪癖和复杂之处,在尝试做复杂的事情时,了解这些怪癖和复杂之处非常有价值。

重新渲染

Blaze 有意地对重新渲染保持不透明。Tracker 和 Blaze 被设计为“最终一致性”系统,最终会完全反映任何数据更改,但可能需要进行几次重新运行或重新渲染才能达到一致,具体取决于它们的用法。如果您试图仔细控制组件何时重新渲染,这可能会令人沮丧。

这里首先要考虑的是,您是否真的需要关心组件的重新渲染。Blaze 经过优化,通常情况下,即使组件严格地说不应该重新渲染,重新渲染也无关紧要。如果您确保您的助手运行成本低廉,从而渲染成本不高,那么您可能不必担心这个问题。

了解 Blaze 如何重新渲染的最主要的一点是,重新渲染发生在助手和模板包含的级别。每当组件的数据上下文发生变化时,它就必须重新运行所有助手和数据访问器(因为助手中的this是数据上下文,因此会发生变化)。

此外,如果从该特定助手内部访问的任何反应式数据源发生变化,助手也会重新运行。

您通常可以跟踪反应式失效的来源来弄清楚助手为什么重新运行。

1
2
3
4
5
6
7
Template.myTemplate.helpers({
helper() {
// When this helper is scheduled to re-run, the `console.trace` will log a stack trace of where
// the invalidation has come from (typically a `changed` message from some reactive variable).
Tracker.onInvalidate(() => console.trace());
}
});

控制重新渲染

如果您的助手或子组件运行成本高昂,并且经常在没有任何可见效果的情况下重新运行,您可以使用更细微的反应式数据源来缩短不必要的重新运行时间。 peerlibrary:computed-field 包有助于实现这种模式。

属性助手

通过助手设置标签属性(例如 <div {{attributes}}>)是一种很巧妙的工具,它有一些优先级规则,使它更有用。具体来说,当您在一个给定元素上多次使用它时,这些属性会被组合(而不是第二个属性集简单地替换第一个)。因此,您可以使用一个助手来设置一组属性,另一个助手来设置另一组属性。例如

1
2
3
<template name="myTemplate">
<div id="my-div" {{classes 'foo' 'bar'}} {{backgroundImageStyle 'my-image.jpg'}}>My div</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
Template.myTemplate.helpers({
classes(names) {
return {class: names.map(n => `my-template-${n}`)};
},
backgroundImageStyle(imageUrl) {
return {
style: {
backgroundImage: `url(${imageUrl})`
}
};
}
});

查找顺序

Blaze 中另一个复杂的话题是名称查找。当您编写 {{something}} 时,Blaze 以什么顺序查找?它按以下顺序运行

  1. 当前组件上定义的助手
  2. 当前范围内的绑定(例如,来自 {{#let}}{{#each in}}
  3. 模板名称
  4. 全局助手
  5. 当前数据上下文上的字段

Blaze 和构建系统

构建系统文章 中所述, blaze-html-templates 包会扫描您的源代码以查找 .html 文件,挑选出 <template name="templateName"> 标签,并将它们编译成一个 JavaScript 文件,该文件定义一个函数,该函数在代码中实现组件,并附加到 Template.templateName 符号。

这意味着当您渲染 Blaze 模板时,您只是在客户端运行一个与您在 .html 文件中定义的 Spacebars 内容相对应的函数。

什么是视图?

Blaze 中最核心的概念之一是“视图”,它是一个构建块,代表模板中一个反应式渲染的区域。视图是幕后起作用的机制,用于跟踪反应式,执行查找,并在数据更改时适当地重新渲染。视图是 Blaze 中重新渲染的单位。您甚至可以使用视图树来遍历渲染的组件层次结构,但最好避免这样做,而应使用回调、模板参数或全局数据存储在组件之间进行通信。

您可以在 Blaze 视图 中阅读有关视图的更多信息。

在 GitHub 上编辑