在结构指令中访问 ViewChildren/ContentChildren

Accessing ViewChildren/ContentChildren in a structural Directive

我想创建一个父指令,它根据子项的值显示或隐藏子项。为此,我采用了父结构指令和带值的子指令的方法。为简单起见,没有值:

<div *appParent>
  <div appChild>1</div>
  <div appChild>2</div>
  <div appChild>3</div>
  <div appChild>4</div>
</div>

要访问子项,我在父指令中使用以下行:

 @ContentChildren(AppChildDirective, { read: AppChildDirective, descendents: true }) children: QueryList<AppChildDirective>;

此查询列表始终为空。但是,当我将其更改为非结构化时,它工作正常。 Stackblitz demo here

我假设这是由于结构指令创建了一个父 ng-template,然后 @ContentChildren 向内查找以找到原始组件,这意味着查询实际上无处可去。

我可以采用什么方法来访问原始组件而不是模板的子组件?还是我需要采取另一种方法来处理我的要求?

ContentChildren 似乎不适用于结构指令。但是,这可以通过在子项中注入父指令,然后通过调用函数在父项中注册子项来实现。

@Directive({
  selector: '[appChild]'
})
export class ChildDirective {
  constructor(parent: ParentDirective) { 
    parent.registerChild(this);
  }
}

@Directive({
  selector: '[appParent]'
})
export class ParentDirective {
  registerChild(child: ChildDirective) { /*...*/ }
}

旁注

如果您还希望能够在没有父指令的情况下使用子指令,请像这样更改子指令的构造函数以使父指令可选:

constructor(@Optional() parent: ParentDirective) { 
  parent?.registerChild(this);
}

您还可以通过在其自己的构造函数中注入指令来递归地使用此方法。如果这样做,还要在构造函数中添加 @SkipSelf() 以真正获取父级:

@Directive({
  selector: '[appRecursive]'
})
export class RecursiveDirective {
  constructor(@Optional() @SkipSelf() parent: RecursiveDirective) { 
    parent?.registerChild(this);
  }

  registerChild(child: RecursiveDirective) { /*...*/ }
}