如何从父组件查询 ng-content 的输入元素

Viv*_*mar 2 typescript angular

创建一个如下所示的组件

<div class="test-search-field"
  [ngClass]="{'expanding': expanding}">
  <ng-content></ng-content>
</div>
Run Code Online (Sandbox Code Playgroud)

此组件的用户将input在使用此组件时添加一个元素。

<my-input-container>
    <input type="search" placeholder="Search">
</my-input-container>
Run Code Online (Sandbox Code Playgroud)

我想从组件中获取这个输入元素,但是在使用@ContentChild.

@ContentChild('input') inputElemRef: ElementRef;

  ngAfterContentInit() {
    setInterval(() => {
      console.log(this.inputElemRef);
    }, 2000);
Run Code Online (Sandbox Code Playgroud)

但这inputElemRef总是未定义的。

谁能告诉我我在这里犯了什么错误。

Tom*_*ula 6

  1. 通过指令类令牌查询。

我的input.directive.ts

import { Directive } from '@angular/core';

@Directive({
  selector: '[myInput]',
})
export class MyInputDirective  {}
Run Code Online (Sandbox Code Playgroud)

my-input-container.component.ts

import { Component, Input, ContentChild, AfterContentInit, ElementRef } from '@angular/core';
import { MyInputDirective } from './my-input.directive';

@Component({
  selector: 'my-input-container',
  template: `<ng-content></ng-content>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class MyInputContainerComponent implements AfterContentInit {
  @ContentChild(MyInputDirective, { read: ElementRef }) child: MyInputDirective;

  ngAfterContentInit() {
    console.log(this.child);
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

<my-input-container>
  <input myInput />
</my-input-container>
Run Code Online (Sandbox Code Playgroud)

现场演示

  1. 通过模板变量查询。

如果您只关心 ElementRef,则可以完全跳过自定义指令,而是通过模板变量进行查询。

我的输入容器.ts

import { Component, Input, ContentChild, AfterContentInit, ElementRef } from '@angular/core';

@Component({
  selector: 'my-input-container',
  template: `<ng-content></ng-content>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class MyInputContainerComponent {
  @ContentChild('myInput') child: ElementRef;

  ngAfterContentInit() {
    console.log(this.child);
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

<my-input-container>
  <input #myInput />
</my-input-container>
Run Code Online (Sandbox Code Playgroud)

现场演示

一般来说,第一个选项是可取的,它对@angular/material输入组件的作用是什么。它们将容器组件 ( mat-form-field) 与应用于本机输入元素 ( matInput)的指令配对。

它更灵活,因为您可以查询 Directive 或 ElementRef。

@ContentChild(MyInputDirective) child: MyInputDirective;

@ContentChild(MyInputDirective, { read: ElementRef }) child: MyInputDirective;