繁体   English   中英

Angular2 - ContentChild查询找不到嵌套组件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM