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

时间:2018-04-10 13:04:16

标签: angular typescript

创建如下组件

import store from 'store.js'

此组件的用户在使用此组件时将添加<div class="test-search-field" [ngClass]="{'expanding': expanding}"> <ng-content></ng-content> </div> 元素。

input

从我想要获取此输入元素的组件中,但在使用<my-input-container> <input type="search" placeholder="Search"> </my-input-container> 查询时出错。

@ContentChild

但是这个@ContentChild('input') inputElemRef: ElementRef; ngAfterContentInit() { setInterval(() => { console.log(this.inputElemRef); }, 2000); 总是未定义。

任何人都可以告诉我我在这里做了什么错误。

2 个答案:

答案 0 :(得分:3)

  1. 通过指令类标记查询。
  2. MY-input.directive.ts

    import { Directive } from '@angular/core';
    
    @Directive({
      selector: '[myInput]',
    })
    export class MyInputDirective  {}
    

    我的输入-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);
      }
    }
    

    用法:

    <my-input-container>
      <input myInput />
    </my-input-container>
    

    Live demo

    1. 按模板变量查询。
    2. 如果你只关心ElementRef,你可以完全跳过自定义指令,而不是通过模板变量进行查询。

      我的输入-container.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);
        }
      }
      

      用法:

      <my-input-container>
        <input #myInput />
      </my-input-container>
      

      Live demo

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

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

      @ContentChild(MyInputDirective) child: MyInputDirective;

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

答案 1 :(得分:1)

我会使用渲染器来做到这一点。

有些人喜欢 stackblitz

ngAfterViewInit() {
  const el = this.renderder.selectRootElement('input');
  console.log(el);
}