昨天介绍了 AsyncPipe 的用法以及它可以带来的便利,今天要来看一下在这方便的背後是由那些东西所组成的。
function AppComponent_ng_container_2_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "p");
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](2);
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpipe"](3, "async");
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "p");
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](5);
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
}
if (rf & 2) {
const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__[
"ɵɵnextContext"
]();
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](
"This is subscribed by AsyncPipe: ",
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpipeBind1"](
3,
2,
ctx_r0.interval1
),
""
);
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](
"This is subscribed manually: ",
ctx_r0.interval2Value,
""
);
}
}
↑ Block 1
在 rf & 1
为 true 的阶段,Angular 会依序透过不同的 instruction 建立 element,在其中我们可以看到先前没有看过的 instruction:ɵɵpipe
。
rf 是 RenderFlags 的缩写。当 rf 被设为 0x01 的时候,代表进入 create block、设为 0x10 时,则进入 update block。相关说明可以参考:Link。
当执行到 ɵɵpipe
这个 instruction 的时候,Angular 会建立指定 pipe 的实体,然後存入当前的 lView 与 tView.data。
最後则会进到 update block,进到这个阶段的时候会有一个 ɵɵadvance
的 instruction,在开始处理 data binding 之前,Angular 会先用这个 instruction 将 element 的定位点移到实际有需要做 data binding 的那个元素的 index。
举例来说,在 _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](2);
这个 index 为 2 的 text 元素有一个 interpolation,所以在进到 update block 时,Angular 就用 ɵɵadvance 把定位点移到 2,接着执行 ɵɵtextInterpolate1
把值填进去。
关於 ɵɵadvance,可以移到这里,了解更多!
做完 interpolation 之後,接着就是做 ɵɵpipeBind1
了。
export function ɵɵpipeBind1(index: number, slotOffset: number, v1: any): any {
const lView = getLView();
const pipeInstance = load<PipeTransform>(lView, index);
return unwrapValue(
lView,
isPure(lView, index) ?
pureFunction1Internal(
lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, pipeInstance) :
pipeInstance.transform(v1));
}
↑ Block 2:ɵɵpipeBind1 的实作
ɵɵpipeBind1 这个 instruction 会根据 pipe 实体来选择要怎麽呼叫 pipe 的 transform 方法,再透过 unwrapValue 来做一些额外的处理,最後将被 pipe 处理过的值传出去给 ɵɵtextInterpolate1 instruction 来更新 text 元素的值。
以上是 Angular 处理 pipe 的流程,因为 AsyncPipe 是一个 impure 的 pipe,所以会直接呼叫 AsyncPipe 的 transform 方法,关於 pure 与 impure 之间的差异,就是明天的内容罗!
以下按照入团顺序列出我们团队夥伴的系列文章!
请自由参阅 ?
<<: Day 26 | Overfitting v.s. Underfitting
想知道我们在使用滑鼠操作电脑时作业系统在背後做了什麽事情吗? 又或者为什麽我们在写 C 语言时,老师...
星期四(12/14)大盘跌幅近一个百分点,市场又是一片哀嚎 散户很容易犯的错就是 大涨不找理由,大跌...
今天要分享的是G-mail寄信的另外一种方式, 虽然比较麻烦, 但是比较安全. 解除人机验证锁定 进...
tags: 2021铁人赛 React 上一篇使用静态的资料,将多张数据资料表画成线图呈现在网页上,...
前言 该系列是为了让看过Vue官方文件或学过Vue但是却不知道怎麽下手去重构现在有的网站而去规画的系...