Angular4-组件交互

组件交互的几种方式

  • 通过输入型绑定把数据从父组件传到子组件
  • 通过setter截听输入属性值的变化
  • 通过ngOnChanges()来截听输入属性值的变化
  • 父组件监听子组件的事件
  • 父组件与子组件通过本地变量互通
  • 父组件调用@viewChild()
  • 父组件和子组件通过服务来通讯

@Input()

//子组件
import { Component, Input } from '@angular/core';
import { Hero } from './hero';

@Component({
  selector: 'app-hero-child',
  template: `
    

{{hero.name}} says:

I, {{hero.name}}, am at your service, {{masterName}}.

` }) export class HeroChildComponent { @Input() hero: Hero; @Input('master') masterName: string; }
//父组件
import { Component } from '@angular/core';
import { HEROES } from './hero';

@Component({
  selector: 'app-hero-parent',
  template: `
    

{{master}} controls {{heroes.length}} heroes

` }) export class HeroParentComponent { heroes = HEROES; master = 'Master'; }

setter

//子组件
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-name-child',
  template: '

"{{name}}"

' }) export class NameChildComponent { private _name = ''; @Input() set name(name: string) { this._name = (name && name.trim()) || ''; } get name(): string { return this._name; } }
//父组件
import { Component } from '@angular/core';

@Component({
  selector: 'app-name-parent',
  template: `
  

Master controls {{names.length}} names

` }) export class NameParentComponent { // Displays 'Mr. IQ', '', 'Bombasto' names = ['Mr. IQ', ' ', ' Bombasto ']; }

ngOnChanges()

//子组件
import { Component, Input, OnChanges, SimpleChange } from '@angular/core';

@Component({
  selector: 'app-version-child',
  template: `
    

Version {{major}}.{{minor}}

Change log:

  • {{change}}
` }) export class VersionChildComponent implements OnChanges { @Input() major: number; @Input() minor: number; changeLog: string[] = []; ngOnChanges(changes: {[propKey: string]: SimpleChange}) { let log: string[] = []; for (let propName in changes) { let changedProp = changes[propName]; let to = JSON.stringify(changedProp.currentValue); if (changedProp.isFirstChange()) { log.push(`Initial value of ${propName} set to ${to}`); } else { let from = JSON.stringify(changedProp.previousValue); log.push(`${propName} changed from ${from} to ${to}`); } } this.changeLog.push(log.join(', ')); } }
//父组件
import { Component } from '@angular/core';

@Component({
  selector: 'app-version-parent',
  template: `
    

Source code version

` }) export class VersionParentComponent { major = 1; minor = 23; newMinor() { this.minor++; } newMajor() { this.major++; this.minor = 0; } }

EventEmitter

//子组件
import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
  selector: 'app-voter',
  template: `
    

{{name}}

` }) export class VoterComponent { @Input() name: string; @Output() onVoted = new EventEmitter(); voted = false; vote(agreed: boolean) { this.onVoted.emit(agreed); this.voted = true; } }
//父组件
import { Component }      from '@angular/core';

@Component({
  selector: 'app-vote-taker',
  template: `
    

Should mankind colonize the Universe?

Agree: {{agreed}}, Disagree: {{disagreed}}

` }) export class VoteTakerComponent { agreed = 0; disagreed = 0; voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto']; onVoted(agreed: boolean) { agreed ? this.agreed++ : this.disagreed++; } }

本地变量

//子组件
import { Component, OnDestroy, OnInit } from '@angular/core';

@Component({
  selector: 'app-countdown-timer',
  template: '

{{message}}

' }) export class CountdownTimerComponent implements OnInit, OnDestroy { intervalId = 0; message = ''; seconds = 11; clearTimer() { clearInterval(this.intervalId); } ngOnInit() { this.start(); } ngOnDestroy() { this.clearTimer(); } start() { this.countDown(); } stop() { this.clearTimer(); this.message = `Holding at T-${this.seconds} seconds`; } private countDown() { this.clearTimer(); this.intervalId = window.setInterval(() => { this.seconds -= 1; if (this.seconds === 0) { this.message = 'Blast off!'; } else { if (this.seconds < 0) { this.seconds = 10; } // reset this.message = `T-${this.seconds} seconds and counting`; } }, 1000); } }
//父组件
import { Component }                from '@angular/core';
import { CountdownTimerComponent }  from './countdown-timer.component';

@Component({
  selector: 'app-countdown-parent-lv',
  template: `
  

Countdown to Liftoff (via local variable)

{{timer.seconds}}
`, styleUrls: ['../assets/demo.css'] }) export class CountdownLocalVarParentComponent { }

@ViewChild()

//父组件
import { AfterViewInit, ViewChild } from '@angular/core';
import { Component }                from '@angular/core';
import { CountdownTimerComponent }  from './countdown-timer.component';

@Component({
  selector: 'app-countdown-parent-vc',
  template: `
  

Countdown to Liftoff (via ViewChild)

{{ seconds() }}
`, styleUrls: ['../assets/demo.css'] }) export class CountdownViewChildParentComponent implements AfterViewInit { @ViewChild(CountdownTimerComponent) private timerComponent: CountdownTimerComponent; seconds() { return 0; } ngAfterViewInit() { // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ... // but wait a tick first to avoid one-time devMode // unidirectional-data-flow-violation error setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0); } start() { this.timerComponent.start(); } stop() { this.timerComponent.stop(); } }

服务

//服务
import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class MissionService {

  // Observable string sources
  private missionAnnouncedSource = new Subject();
  private missionConfirmedSource = new Subject();

  // Observable string streams
  missionAnnounced$ = this.missionAnnouncedSource.asObservable();
  missionConfirmed$ = this.missionConfirmedSource.asObservable();

  // Service message commands
  announceMission(mission: string) {
    this.missionAnnouncedSource.next(mission);
  }

  confirmMission(astronaut: string) {
    this.missionConfirmedSource.next(astronaut);
  }
}
//子组件
import { Component, Input, OnDestroy } from '@angular/core';

import { MissionService } from './mission.service';
import { Subscription }   from 'rxjs/Subscription';

@Component({
  selector: 'app-astronaut',
  template: `
    

{{astronaut}}: {{mission}}

` }) export class AstronautComponent implements OnDestroy { @Input() astronaut: string; mission = ''; confirmed = false; announced = false; subscription: Subscription; constructor(private missionService: MissionService) { this.subscription = missionService.missionAnnounced$.subscribe( mission => { this.mission = mission; this.announced = true; this.confirmed = false; }); } confirm() { this.confirmed = true; this.missionService.confirmMission(this.astronaut); } ngOnDestroy() { // prevent memory leak when component destroyed this.subscription.unsubscribe(); } }
//父组件
import { Component }          from '@angular/core';

import { MissionService }     from './mission.service';

@Component({
  selector: 'app-mission-control',
  template: `
    

Mission Control

History

  • {{event}}
`, providers: [MissionService] }) export class MissionControlComponent { astronauts = ['Lovell', 'Swigert', 'Haise']; history: string[] = []; missions = ['Fly to the moon!', 'Fly to mars!', 'Fly to Vegas!']; nextMission = 0; constructor(private missionService: MissionService) { missionService.missionConfirmed$.subscribe( astronaut => { this.history.push(`${astronaut} confirmed the mission`); }); } announce() { let mission = this.missions[this.nextMission++]; this.missionService.announceMission(mission); this.history.push(`Mission "${mission}" announced`); if (this.nextMission >= this.missions.length) { this.nextMission = 0; } } }
Angular4-组件交互_第1张图片
公众号:前端咖秀

你可能感兴趣的:(Angular4-组件交互)