组件之间会有下列3种关系:
1. 父子关系
2. 兄弟关系
3. 没有直接关系
通常采用下列方式处理(某些方式是框架特有)组件间的通讯,如下:
1父子组件之间的交互(@Input/@Output/模板变量/@ViewChild)
2非父子组件(Service/localStorage)
3还可以利用Session等服务器端的解决方法
Angular组件间通讯方法:
1、父子组件之间的通讯
@Input:是属性绑定,父组件向子组件传递数据
@Output:是事件绑定,子组件向父组件传递数据的同时触发事件
1.1在父组件设置子组件上面的的属性
通过@input绑定子组件的属性,注意属性得是公开public的,私有private属性是无法传递的
es6新语法get/set.为属性提供了一个方便习惯的读/写方式, 拦截属性的存取行为。
在父组件设置该属性,就能够通过set方法来修改,从而实现在父组件设置子组件属性
子组件
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-child', template: '<h1>{{childTitle}}</h1>' }) export class ChildComponent implements OnInit { private _childTitle: string = '子组件标题'; @Input() set childTitle(childTitle: string) { this._childTitle = childTitle; } get childTitle(): string { return this._childTitle; } constructor() { } ngOnInit() { } }
父组件
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-parent', templateUrl: '<p>parent-and-child works!</p><app-child childTitle=“可设置子组件标题”></app-child>' }) export class ParentAndChildComponent implements OnInit { constructor() { } ngOnInit() { } }
1.2父组件直接调用子组件的方法
通过模板内部定义子组件变量,在父组件上可以直接调用子组件的方法,如下:
子组件
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-child', templateUrl: '<p>child work</p>' }) export class ChildComponent implements OnInit { constructor() { } ngOnInit() { } childPrint() { alert("来自子组件的打印"); } }
父组件
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-parent', templateUrl: '<p>parent-and-child works!</p><app-child #child></app-child> <button (click)="child.childPrint()"></button>' }) export class ParentAndChildComponent implements OnInit { constructor() { } ngOnInit() { } }
1.3父组件接受子组件派发的事件
通过@Output在子组件绑定一个事件发射器,在父组件通过事件绑定监听该事件
这样在子组件派发一个事件,父组件就能够收到
子组件
import { Component, OnInit, Output, EventEmitter} from '@angular/core'; @Component({ selector: 'app-child', templateUrl: '<p>child work</p>' }) export class ChildComponent implements OnInit { @Output() initEmit = new EventEmitter<string>(); constructor() { } ngOnInit() { this.initEmit.emit("子组件初始化成功"); } }
父组件
import { Component, OnInit, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-parent', templateUrl: '<p>parent-and-child works!</p><app-child (initEmit)="accept($event)"></app-child>' }) export class ParentAndChildComponent implements OnInit { constructor() { } ngOnInit() { } accept(msg:string) { alert(msg); } }
2、没有直接关系的组件
2.1service
做一个全局单例的service,然后多个组件共享这个实例,当然就可以共享其中的成员,来进行通讯。
只需将service注入到组件中就可在组件中使用该service中提供的变量和方法。
2.2路由传值
对于2个不同路由的组件,我们也可以通过路由传递信息
假设2个路由分别为~/home,~/about
2.2.1传递一个值
url: /about/:id
<button [routerLink]="['/about',1]">跳转</button>
获取传入的值:
this.id = this.route.snapshot.params['id'];
2.2.2传递一个对象
类似于上述的传递一个值,但是不需要再路由末尾加上/:id
url: /about
<button [routerLink]="['/about']" [queryParams]="{id:12,status:true}">跳转</button>
this.route.queryParams.subscribe((params: Params)=>{
this.id = params['id'];
this.status = params['status'];
})
3通用方式实现通讯
3.1localstorage处理
在angular中也可以使用本地存储这种比较通用的方式在组件间通讯,但本地存储有下列弊端:
1存储空间有限
2只能存储字符串
setData(){ window.localStorage.setItem("test", JSON.stringify({ key: 'test', value: 1 })); } getData() { var json = window.localStorage.getItem("test"); var obj = JSON.parse(json); console.log(obj.key); console.log(obj.value); }
3.2服务端处理
也可以在服务端来处理组件间的通讯问题,通过接口调用存储或获取数据
转自:https://www.cnblogs.com/banluduxing/p/9290569.html