[英]Angular2 - ContentChild query does not find nested components
我正在尝试设置一个Angular2组件,该组件自动聚焦通过内容投影插入的输入元素。
我使用的解决方案基于这个答案 。 我有一个额外的要求,即input元素可能嵌套在另一个组件中。 但是,我发现ContentChild
查询无法检测深埋在ng-content
标记内的元素。
@Component({
selector: 'inner-feature',
template: "<input auto-focus>",
directives: [AutoFocus]
})
export class InnerFeature { }
@Component({
selector: 'feature',
template: `
<div [class.hide]="!show">
<ng-content></ng-content>
</div>
`
})
export class Feature {
@ContentChild(AutoFocus)
private _autoFocus: AutoFocus;
private _show: boolean = false;
@Input()
get show() {
return this._show;
}
set show(show: boolean) {
this._show = show;
if (show && this._autoFocus) {
setTimeout(() => this._autoFocus.focus());
}
}
}
@Component({
selector: 'my-app',
template: `
<div>
<button (click)="toggleFeature()">Toggle</button>
<feature [show]="showFeature">
<inner-feature></inner-feature>
</feature>
</div>
`,
directives: [Feature, InnerFeature]
})
export class App {
showFeature: boolean = false;
toggleFeature() {
this.showFeature = !this.showFeature;
}
}
永远不会填充_autoFocus
属性。 与auto-focus
指令没有嵌套在另一个组件内并且工作正常的情况形成对比。 有没有办法让这项工作?
(我没有粘贴AutoFocus
的代码,因为它对这个例子并不重要。)
有关演示,请参阅Plunker 。
更新上面的代码来修复丢失的指令。
使用ContentChildren
并将descendants
设置为true
@ContentChildren(AutoFocus, { descendants: true })
实际上我想在这个问题上花更多的时间来寻找更好的解决方案,但是现在我提出了以下可能对你有帮助的方法:
首先,你必须揭露AutoFocus
的内部InnerFeatures
(和你忘了添加AutoFocus
到您的阵列directives
)使用@ViewChild
。 这看起来像这样:
@Component({
selector: 'inner-feature',
template: "<input auto-focus>",
directives: [AutoFocus]
})
export class InnerFeature {
@ViewChild(AutoFocus)
autoFocus:AutoFocus;
}
然后在您的父组件Feature
您可以使用@ContentChildren
返回绑定组件的QueryList
(在您的情况下为InnerFeature
)。
在show
方法中(或者例如在ngAfterContentInit
中或之后),您可以访问此InnerFeatures
列表:
export class Feature implements OnInit {
@ContentChild(AutoFocus)
private _autoFocus: AutoFocus;
@ContentChildren(InnerFeature)
private _innerFeatures: QueryList<InnerFeature>;
private _show: boolean = false;
@Input()
get show() {
return this._show;
}
set show(show: boolean) {
this._show = show;
if (show) {
setTimeout(() => {
if (this._autoFocus) {
this._autoFocus.focus();
}
if (this._innerFeatures) {
this._innerFeatures.map((innerFeature) => {
innerFeature.autoFocus.focus();
});
}
});
}
}
ngAfterContentInit() {
console.log(this._autoFocus);
console.log(this._innerFeatures);
}
}
我修改了你的plunker ,所以你可以测试它的行动。
可能不像你想要的那样充满活力,但是,我希望它无论如何都有帮助。
如果在英格兰对阵赛后的比赛中没有更好的答案,我会尝试提出一个更好的方法;)
更新 :我更新了我的代码,因为它在访问_results
时引发了错误。 使用map()
代替QueryList
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.