我正在尝试设置一个Angular2组件,该组件自动聚焦通过内容投影插入的输入元素。
我使用的解决方案基于this answer。我有一个额外的要求,即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了解演示。
上面的更新代码修复了缺失的指令。
答案 0 :(得分:4)
在ContentChildren
设置为descendants
true
@ContentChildren(AutoFocus, { descendants: true })
答案 1 :(得分:2)
实际上我想在这个问题上花更多的时间来寻找更好的解决方案,但是现在我想出了以下可能对你有所帮助:
首先,您必须使用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
。