30秒学会 Angular 片段 · 2020年2月23日

30秒学会 Angular 片段 – Getting components of different types with ViewChild

It’s possible to use @ViewChild (also @ViewChildren and @ContentChild/Children) to query for components of different types using dependency injection.

In the example below we can use @ViewChildren(Base) to get instances of Foo and Bar.

abstract class Base {}

@Component({
  selector: 'foo',
  providers: [{ provide: Base, useExisting: Foo }]
})
class Foo extends Base {}

@Component({
  selector: 'bar',
  providers: [{ provide: Base, useExisting: Bar }]
})
class Bar extends Base {}

// Now we can require both types of components using Base.
@Component({ template: `<foo></foo><bar></bar>` })
class AppComponent {
  @ViewChildren(Base) components: QueryList<Base>;
}

file:app.component.ts

import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';

export abstract class Animal {
  abstract say();
}

@Component({
  selector: 'fox',
  template: `🦊`,
  providers: [{ provide: Animal, useExisting: Fox }]
})
export class Fox extends Animal {
  say() {
    console.log('Joff-tchoff-tchoffo-tchoffo-tchoff!');
  }
}

@Component({
  selector: 'rice',
  template: `🍚`,
  providers: [{ provide: Animal, useExisting: Rice }]
})
export class Rice extends Animal {
  say() {
    console.log('lol');
  }
}

@Component({
  selector: 'dragon',
  template: `🐉`,
  providers: [{ provide: Animal, useExisting: Dragon }]
})
export class Dragon extends Animal {
  say() {
    console.log('Wa-pa-pa-pa-pa-pa-pow!');
  }
}

@Component({
  selector: 'my-app',
  template: `
    <fox></fox>
    <rice></rice>
    <dragon></dragon>
  `
})
export class AppComponent implements AfterViewInit {
  @ViewChildren(Animal) animals: QueryList<Animal>;

  ngAfterViewInit() {
    animals.forEach((animal) => animal.say());
  }
}

file:app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent, Fox, Rice, Dragon } from './app.component';

@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent, Fox, Rice, Dragon],
  bootstrap: [AppComponent]
})
export class AppModule {}

翻译自:https://www.30secondsofcode.org/angular/s/getting-components-of-different-types-with-viewchild

相关链接