组件间通信

187 阅读2分钟

父子通信

父组件: 通过子组件的自定义属性向下传递数据给子组件

// myc01-parent-blog.component.html
  <!-- 子组件 -->
  <app-myc03-child2-photo [child2Name]="userName"></app-myc03-child2-photo>

// myc01-parent-blog.component.ts
export class Myc01ParentBlogComponent implements OnInit {
  public userName:String = '苍茫大地001'
}

子组件

// myc03-child2-photo.component.html
<h3>{{child2Name}}的照片墙</h3>

// myc03-child2-photo.component.ts
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-myc03-child2-photo',
  templateUrl: './myc03-child2-photo.component.html',
  styleUrls: ['./myc03-child2-photo.component.css']
})
export class Myc03Child2PhotoComponent implements OnInit {
  // 普通属性不能被父组件传值
  // public child2Name:string = ''

  // 输入型属性:父组件可以利用这种属性传值进来
  @Input()
  public child2Name:String = ''
  constructor() { }

  ngOnInit(): void {
  }

}

注意:装饰器只能装饰紧贴着的代码

子父通信

子组件通过触发特定的事件(其中携带着数据),把数据传递给父组件(父组件提供事件处理方法

子组件
// myc02-child1-modify.component.html
<div>
  <input [(ngModel)]="userInput" type="text">
  <button (click)="doModify()">修改我的用户名</button>
</div>

// myc02-child1-modify.component.ts

import { Component, EventEmitter, OnInit, Output } from '@angular/core';

@Component({
  selector: 'app-myc02-child1-modify',
  templateUrl: './myc02-child1-modify.component.html',
  styleUrls: ['./myc02-child1-modify.component.css']
})
export class Myc02Child1ModifyComponent implements OnInit {

  public userInput:string = ''

  // 事件发射器
  @Output() // 输出型属性,可以向父组件输出数据
  public cryEvent = new EventEmitter()

  doModify(){
    // 子组件将要传递给父组件的数据
    console.log(this.userInput);
    // 子组件此时想发射数据给父组件  
    this.cryEvent.emit(this.userInput)
  }

  constructor() { }


  ngOnInit(): void {
  }

}
父组件
// myc01-parent-blog.component.html
<div>
  <h2>{{userName}}的博客</h2>
  <!-- 子组件 -->
  <app-myc02-child1-modify (cryEvent)="doCry($event)"></app-myc02-child1-modify>
</div>

// myc01-parent-blog.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-myc01-parent-blog',
  templateUrl: './myc01-parent-blog.component.html',
  styleUrls: ['./myc01-parent-blog.component.css']
})
export class Myc01ParentBlogComponent implements OnInit {

  public userName:String = '苍茫大地001'

  // 处理子组件的“cryEvent”
  doCry(e:any){
    console.log('e',e); // 自定义事件发射过来的数据
    this.userName = e
  }

  constructor() { }
  ngOnInit(): void {
  }
}

父组件向子组件传递数据的简便方法

// myc01-parent-blog.component.html
<div #c0>
  <h2>{{userName}}的博客</h2>
  <hr>
  <!-- 第一个子组件 -->
  <app-myc02-child1-modify #c1></app-myc02-child1-modify>
 
  <!-- 第二个子组件 -->
  <app-myc03-child2-photo #c2></app-myc03-child2-photo>

  <hr>
  <button (click)="print()">输出内部有识别符的子组件</button>
</div>


// myc01-parent-blog.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-myc01-parent-blog',
  templateUrl: './myc01-parent-blog.component.html',
  styleUrls: ['./myc01-parent-blog.component.css']
})
export class Myc01ParentBlogComponent implements OnInit {

  public userName:String = '苍茫大地001'

  @ViewChild('c0',{static:true})
  private c0:unknown;
  @ViewChild('c1',{static:true})
  private c1:unknown;
  @ViewChild('c2',{static:true})
  private c2:unknown;

  // 输出父组件内部的有识别符的子组件
  print(){
    console.log(this.c0,this.c1,this.c2); 
  }

  constructor() { }

  ngOnInit(): void {
  }

}

注意: 通过“ViewChild” 视图子组件方式,父组件可以获得任意子组件的任意数据 -- 一定程度上违法了 “最少知识法则”