在结构指令中访问 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) { /*...*/ }
}
我想创建一个父指令,它根据子项的值显示或隐藏子项。为此,我采用了父结构指令和带值的子指令的方法。为简单起见,没有值:
<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) { /*...*/ }
}