微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular组件之间的交互

Angular组件之间常用交互方法

通过输入型绑定把数据从父组件传到子组件

child.component.ts

export class ChildComponent implements OnInit {
  @input() hero: any;
  @Input('master') masterName: string;      // 第二个 @Input 为子组件的属性名 masterName 指定一个别名 master

  constructor() { }

  ngOnInit(): void {
  }

}

child.component.html

<div style="background-color: #749f84">
  <p>child works!</p>
  <h3>{{hero?.name}} says:</h3>
  <p>I, {{hero?.name}}, am at your service, {{masterName}}.</p>
</div>

parent.component.ts

export class ParentComponent implements OnInit {
  hero = {name: 'qxj'}
  master = 'Master'

  constructor() {
  }

  ngOnInit(): void {
  }

}

parent.component.html

<app-child [hero]="hero" [master]="master"></app-child>

父组件监听子组件的事件

child.component.ts

export class ChildComponent implements OnInit {
  @input()  name: string;
  @Output() Voted = new EventEmitter<boolean>();
  didVote = false;

  Vote(agreed: boolean) {
    this.Voted.emit(agreed);
    this.didVote = true;
  }

  constructor() { }

  ngOnInit(): void {
  }

}

child.component.html

<h4>{{name}}</h4>
<button (click)="Vote(true)"  [disabled]="didVote">Agree</button>
<button (click)="Vote(false)" [disabled]="didVote">disagree</button>

parent.component.ts

export class ParentComponent implements OnInit {
  agreed = 0
  disagreed = 0
  Voters = ['Narco', 'Celeritas', 'Bombasto']

  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++
  }

  constructor() {
  }

  ngOnInit(): void {
  }

}

parent.component.html

<h2>Should mankind colonize the Universe?</h2>
<h3>Agree: {{agreed}}, disagree: {{disagreed}}</h3>
<app-child *ngFor="let Voter of Voters" [name]="Voter" (Voted)="onVoted($event)"></app-child>

image-20201104233222935

父组件与子组件通过本地变量互动

父组件不能使用数据绑定来读取子组件的属性调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性调用子组件的方法,如下例所示。

子组件 CountdownTimerComponent 进行倒计时,归零时发射一个导弹。startstop 方法负责控制时钟并在模板里显示倒计时的状态信息。

child.component.ts

export class ChildComponent 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)
  }

}

child.component.html

<p>{{message}}</p>

parent.component.ts

export class ParentComponent implements OnInit {
  constructor() {
  }
  ngOnInit(): void {
  }
}

parent.component.html

<h3>Countdown to Liftoff (via local variable)</h3>
<button (click)="child.start()">Start</button>
<button (click)="child.stop()">Stop</button>
<div class="seconds">{{child.seconds}}</div>
<app-child #child></app-child>

countdown timer

父组件调用*@ViewChild()*

这个本地变量方法是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。

如果父组件的需要读取子组件的属性值或调用子组件的方法,就不能使用本地变量方法

当父组件需要这种访问时,可以把子组件作为 ViewChild,***注入***到父组件里面。

countdown-parent.component.ts

import {AfterViewInit, Component, ViewChild} from '@angular/core'
import {ChildComponent} from '../child/child.component'

@Component({
  selector: 'app-parent-vc',
  template: `
    <h3>Countdown to Liftoff (via ViewChild)</h3>
    <button (click)="start()">Start</button>
    <button (click)="stop()">Stop</button>
    <div class="seconds">{{ seconds() }}</div>
    <app-child></app-child>
  `,
})
export class CountdownParentComponent implements AfterViewInit {

  @ViewChild(ChildComponent)
  private timerComponent: ChildComponent

  seconds() {
    return 0
  }

  ngAfterViewInit() {
    // redefine `seconds()` to get from the `ChildComponent.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()
  }
}

项目实例:alan-desk index模块中header和sidebar交互

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐