Angular父组件与子组件交互/组件间交互/组件间数据和事件交互示例


一、数据通信

1.父组件向子组件传递

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

在子组件中定义变量:

@Input() childVariable = "";

在子组件模板中输出该变量:

<p>{
   
   {childVariable}}</p>

在父组件中定义变量:

parentVariable = ""

在父组件模板中输入该变量值:

<p>父组件</p>
<app-person [childVariable]="parentVariable"></app-person>
<input type="text" [(ngModel)]="parentVariable">

这种方式,在子组件中定义了输入型属性(@Input),并通过该属性,在父组件中给子组件传递数据。

b.通过 setter 截听输入属性值的变化

与输入型属性绑定方式类似,在子组件中定义输入型的getter setter方法(@Input),并通在父组件中调用该属性的getter setter方法,达到了向子组件传递数据的目的。
在子组件中定义变量:

  _childName = "";

  @Input()
  get childName() : string {
    
    
    return this._childName
  }

  set childName(name : string) {
    
    
    this._childName = name
  }

在子组件模板中输出该变量:

<p>{
   
   {childName}}</p>

在父组件中定义变量:

myChildName = ""
<p>父组件</p>
<app-person [childName] = "myChildName"></app-person>
<input type="text" [(ngModel)] = "myChildName">

这种方式,通过在父组件中设置子组件的属性,调用了子组件改属性的getter setter方法,从而通过getter setter方法,实现了在父组件中给子组件传递数据。

扫描二维码关注公众号,回复: 14459396 查看本文章

夜半子时,今天先写到这~

2021.11.10 继续ing

2.父组件监听子组件事件

原理:子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。

子组件的 EventEmitter 属性是一个输出属性,通常带有@Output 装饰器:

  @Input() name = ""
  @Output() voted = new EventEmitter<boolean>();
  didVote = false;
  
  vote(agreed : boolean) {
    
    
    this.voted.emit(agreed);
    this.didVote = true;
  }

在子组件模板中:

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

父组件:

  agreed = 0;
  disagreed = 0;
  voters = ['test1', 'test2', 'test3'];

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

父组件模板:

  <h2>Should mankind colonize the Universe?</h2>
  <h3>Agree: {
   
   {agreed}}, Disagree: {
   
   {disagreed}}</h3>
  <app-emittertest *ngFor="let voter of voters" [name] = "voter" (voted) = "onVoted($event)"></app-emittertest>

3.父组件与子组件通过变量互动

a.本地变量

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

  intervalId = 0;
  message = "";
  seconds = 0;

  start() {
    
    
    this.startTiming();
  }

  suspend() {
    
    
    this.clearTimer();
    this.message = this.seconds + "Holding...."
  }

  stop() {
    
    
    this.clearTimer();
    this.seconds = 0;
    this.message = "Stop."
  }

子组件模板:

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

父组件模板:

    <app-timertest #timer></app-timertest>
	<button (click)="timer.start()">start</button>
	<button (click)="timer.stop()">stop</button>
	<button (click)="timer.suspend()">suspend</button>

b.@ViewChild

本地变量方法有一定局限性,因为父组件与子组件的连接必须全部在父组件的模板(HTML)中进行。父组件本身的代码(ts)对子组件没有访问权。
当父组件类需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。
子组件:

  intervalId = 0;
  message = "";
  seconds = 0;

  start() {
    
    
    this.startTiming();
  }

  suspend() {
    
    
    this.clearTimer();
    this.message = this.seconds + "Holding...."
  }

  stop() {
    
    
    this.clearTimer();
    this.seconds = 0;
    this.message = "Stop."
  }

子组件模板

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

父组件:

  @ViewChild(TimerviewchildtestComponent)
  private timertester !: TimerviewchildtestComponent;

  start() {
    
    
    this.timertester.start();
  }

  stop() {
    
    
    this.timertester.stop();
  }

  suspend() {
    
    
    this.timertester.suspend();
  }

父组件模板:

	<app-timerviewchildtest></app-timerviewchildtest>
	<button (click)="start()">start</button>
	<button (click)="stop()">stop</button>
	<button (click)="suspend()">suspend</button>

4.父组件和子组件通过服务来通讯

父组件和它的子组件共享同一个服务,利用该服务在组件家族内部实现双向通讯。
该服务实例的作用域被限制在父组件和其子组件内。这个组件子树之外的组件将无法访问该服务或者与它们通讯。
子组件:

  message = "";

  constructor(private commonService : CommonService) {
    
    

  }

  toParent() {
    
    
    this.commonService.variable2 = "Hello, this is a message from child."
  }

  getMessage() {
    
    
    this.message = this.commonService.variable1;
  }

子组件模板:

    <p>子组件</p><br>
	<p>{
   
   {message}}</p><button (click)="getMessage()">获取消息</button><br>
	<button (click)="toParent()">子 to 父</button><br>

父组件:

  message = "";
  constructor(private commonService : CommonService) {
    
    
    
  }

  toChild() {
    
    
    this.commonService.variable1 = "Hello, this is a message from parent."
  }

  getMessage() {
    
    
    this.message = this.commonService.variable2;
  }

父组件模板:

    <p>{
   
   {message}}</p><button (click)="getMessage()">获取消息</button><br>
	<button (click)="toChild()">父 to 子</button><br>
	<app-twowaycommunicationtest></app-twowaycommunicationtest>

service服务:

@Injectable({
    
    
  providedIn: 'root'
})
export class CommonService {
    
    

  constructor() {
    
     }

  variable1 = "";
  variable2 = "";
}

猜你喜欢

转载自blog.csdn.net/verkand1/article/details/121172590