角5:为所有ContentChildren(甚至子组件中的那些)获取一个QueryList

时间:2018-07-05 12:34:23

标签: javascript html angular directive

我具有以下html结构,其中foobar是两个指令,而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_barsFooDirective的长度为1。它仅包含div的直接子元素<div foo>。但是,我希望该数字为3(<div foo>的一个直接子元素,而另外两个div组成的baz的子元素)。

为什么会这样,如何解决这个问题-如果可以完全解决?

编辑1: 将ContentChildren装饰器更改为

@ContentChildren(BarDirective, { descendants: true })
m_bars: QueryList<BarDirective>;

根本没有任何作用。

2 个答案:

答案 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可能意味着一件事,而在另一个模板中则意味着完全不同的事情。名称可能相同,但含义完全不同。