正如我们所知,仅在最后匹配的 ng-content 中使用 ng-content 项目内容,但我不明白的是,为什么在仅将 select 和项目用于第一个时它的行为相反。
第一个子组件
1
<ng-content select=".my-class"></ng-content> <br>
2
<ng-content select=".my-class"></ng-content>
第二个子组件
1
<ng-content></ng-content> <br>
2
<ng-content></ng-content>
父组件
<app-first>
<ng-container class="my-class">CHILD</ng-container>
</app-first>
<br>--------<br>
<app-second>
<ng-container class="my-class">CHILD</ng-container>
</app-second>
结果
1 CHILD
2
--------
1
2 CHILD
Angular 编译器计算所谓的ngContentIndex
. 您可以将其视为应该投影嵌入节点的地方。
所以,有AppComponent
模板
<app-first>
<ng-container class="my-class">CHILD</ng-container>
</app-first>
<br>--------<br>
<app-second>
<ng-container class="my-class">CHILD</ng-container>
</app-second>
Angular 为每个节点提供了它的ngContentIndex
(看看括号):
<app-first>(null)
<ng-container class="my-class">CHILD</ng-container>(1)
</app-first>
<br>--------<br>(null)
<app-second>(null)
<ng-container class="my-class">CHILD</ng-container>(0)
</app-second>
这意味着第一个CHILD
应该转到第二个 ng-content,第二个应该转到CHILD
第一个。
答案在于 Angular 编译器的源代码。
默认情况下<ng-content></ng-content>
与
<ng-content select="*"></ng-content>
对于每个模板,Angular 都知道它的所有内容ngContentSelectors
:
FirstComponent ['*', '*']
SecondComponent ['.my-class', '.my-class']
这是答案:
const ngContentSelectors = component.directive.template !.ngContentSelectors;
for (let i = 0; i < ngContentSelectors.length; i++) {
const selector = ngContentSelectors[i];
if (selector === '*') {
wildcardNgContentIndex = i;
} else {
matcher.addSelectables(CssSelector.parse(ngContentSelectors[i]), i);
}
}
您可以看到 Angular 进行了*
特殊处理并wildcardNgContentIndex
在循环中更新,因此它将是1
. 对于['.my-class', '.my-class']
数组,它将选择器添加到匹配项。
最后,Angular 使用这种方法:
findNgContentIndex(selector: CssSelector): number | null {
const ngContentIndices: number[] = [];
this._ngContentIndexMatcher.match(selector, (selector, ngContentIndex) => {
ngContentIndices.push(ngContentIndex);
});
ngContentIndices.sort();
if (this._wildcardNgContentIndex != null) {
ngContentIndices.push(this._wildcardNgContentIndex);
}
return ngContentIndices.length > 0 ? ngContentIndices[0] : null;
}
这将返回 中1
可投影节点的保存值FirstComponent
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句