父子通信
父组件: 通过子组件的自定义属性向下传递数据给子组件
// 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” 视图子组件方式,父组件可以获得任意子组件的任意数据 -- 一定程度上违法了 “最少知识法则”