我具有以下html结构,其中foo
和bar
是两个指令,而baz
是自定义组件。
<div foo>
<div bar></div>
<baz><baz>
<baz><baz>
</div>
baz
组件的html看起来像...
<div bar>Yada Yada Yada</div>
...和foo
伪指令看起来像这样:
// ...
@Directive({
selector: '[foo]'
})
export class FooDirective implements AfterContentInit {
@ContentChildren(BarDirective)
m_bars: QueryList<BarDirective>;
public ngAfterContentInit(): void {
console.log('barCount:', this.m_bars.length);
}
}
我遇到的问题是m_bars
中FooDirective
的长度为1。它仅包含div
的直接子元素<div foo>
。但是,我希望该数字为3(<div foo>
的一个直接子元素,而另外两个div
组成的baz
的子元素)。
为什么会这样,如何解决这个问题-如果可以完全解决?
编辑1:
将ContentChildren
装饰器更改为
@ContentChildren(BarDirective, { descendants: true })
m_bars: QueryList<BarDirective>;
根本没有任何作用。
答案 0 :(得分:0)
签出此StackBlitz(注意控制台输出): https://stackblitz.com/edit/angular-h7ybb3
您必须通过输出将其链接起来。 QueryList具有可观察到的更改,您可以尝试将其用作输出。遵循这些原则:
@ContentChildren() something: QueryList<Type>;
@Output() queryListChange = new EventEmitter();
ngOnInit() {
this.something.changes.subscribe(v => {
this.queryListChange.emit(v);
}
}
在上部组件中,您需要订阅此输出:
(queryListChange)="onQueryListChange($event)"
在onQueryListChange中,您需要将收到的那些项与组件自己的ViewChildren合并。
如果需要更多级别的嵌套,则以相同的方式传递它。
我不知道一种合并QueryList的方法,因此我只是从它们中获取原始数组并将它们合并到我的stackblitz中。
答案 1 :(得分:0)
这是不可能的,这很糟糕。有关更多信息,请参见https://github.com/angular/angular/issues/20810#issuecomment-401341413。我将引用tl; dr版本作为参考:
简而言之:我们仅查询组件自己的内容,而不查询来自其他模板的内容。这是有道理的,因为模板在一个模板中形成命名空间#foo可能意味着一件事,而在另一个模板中则意味着完全不同的事情。名称可能相同,但含义完全不同。