首页 > 其他 > 详细

Angular6.x学习笔记——组件详解之组件通讯

时间:2018-07-24 16:44:34      阅读:164      评论:0      收藏:0      [点我收藏+]

目录                                                

 1 前言

 2 Angular组件间的通讯

   2.1 父子组件间的通讯

     2.1.1 父组件设置子组件属性

     2.1.2 父组件调用子组件事件

     2.1.3 子组件向父组件发射事件

   2.2 非父子组件通讯

     2.2.1 Service

     2.2.2 路由传值

       2.2.2.1 传递一个值

       2.2.2.2 传递一个对象

 3 通用方式实现通讯

   3.1 localStorage

   3.2 服务端

4结语

  

1前言

前端框架,例如extjs,vue,angular等,都是或趋于组件化,所以组件间的通讯,是一个亟需解决的问题

一般而且言,这些组件之间都会形成这种树形结构

技术分享图片

               图片来源:大漠穷秋

组件之间会有下列3种关系:

1父子关系

2兄弟关系

3没有直接关系

 

通常采用下列方式处理(某些方式是框架特有)组件间的通讯,如下:

1父子组件之间的交互(@Input/@Output/模板变量/@ViewChild)

2非父子组件(Service/localStorage)

3还可以利用Session等服务器端的解决方法

 

2Angular组件间的通讯

2.1父子组件之间的通讯

在父子组件之间通讯:

 @Input:是属性绑定,父组件向子组件传递数据

 @Output:是事件绑定,子组件向父组件传递数据的同时触发事件

 

2.1.1在父组件设置子组件上面的的属性

通过@input绑定子组件的属性,注意属性得是公开public的,私有private属性是无法传递的

es6新语法get/set.为属性提供了一个方便习惯的读/写方式, 拦截属性的存取行为。

在父组件设置该属性,就能够通过set方法来修改,从而实现在父组件设置子组件属性

代码如下

技术分享图片
1   <h1>{{childTitle}}</h1>
子组件模板文件
技术分享图片
 1 import { Component, OnInit, Input } from @angular/core;
 2 
 3 @Component({
 4   selector: app-child,
 5   templateUrl: ./child.component.html,
 6   styleUrls: [./child.component.sass]
 7 })
 8 export class ChildComponent implements OnInit {
 9 
10   private _childTitle: string = 子组件标题;
11 
12   @Input()
13   set childTitle(childTitle: string) {
14     this._childTitle = childTitle;
15   }
16   get childTitle(): string {
17     return this._childTitle;
18   }
19 
20   constructor() { }
21 
22   ngOnInit() {
23 
24   }
25 }
子组件Ts文件
技术分享图片
1 <p>
2   parent-and-child works!
3 </p>
4 <app-child childTitle="可设置子组件标题"></app-child>
父组件模板文件
技术分享图片
 1 import { Component, OnInit } from @angular/core;
 2 
 3 @Component({
 4   selector: app-parent,
 5   templateUrl: ./parent-and-child.component.html,
 6   styleUrls: [./parent-and-child.component.sass]
 7 })
 8 export class ParentAndChildComponent implements OnInit {
 9 
10   constructor() { }
11 
12   ngOnInit() {
13 
14   }
15 
16 }
父组件Ts文件

 

2.1.2父组件直接调用子组件的方法

通过模板内部定义子组件变量,在父组件上可以直接调用子组件的方法,如下:

技术分享图片
1 <p>child work</p>
子组件模板文件
技术分享图片
 1 import { Component, OnInit, Input } from @angular/core;
 2 
 3 @Component({
 4   selector: app-child,
 5   templateUrl: ./child.component.html,
 6   styleUrls: [./child.component.sass]
 7 })
 8 export class ChildComponent implements OnInit {
 9   constructor() { }
10 
11   ngOnInit() {
12 
13   }
14 
15   childPrint() {
16     alert("来自子组件的打印");
17   }
18 }
子组件Ts文件
技术分享图片
1 <p>
2   parent-and-child works!
3 </p>
4 <app-child #child></app-child>
5 <button (click)="child.childPrint()"></button>
父组件模板文件
技术分享图片
 1 import { Component, OnInit } from @angular/core;
 2 
 3 @Component({
 4   selector: app-parent,
 5   templateUrl: ./parent-and-child.component.html,
 6   styleUrls: [./parent-and-child.component.sass]
 7 })
 8 export class ParentAndChildComponent implements OnInit {
 9 
10   constructor() { }
11 
12   ngOnInit() {
13 
14   }
15 
16 }
父组件Ts文件

 

2.1.3父组件接受子组件派发的事件

通过@Output在子组件绑定一个事件发射器,在父组件通过事件绑定监听该事件

这样在子组件派发一个事件,父组件就能够收到

技术分享图片
1 <p>child work</p>
子组件模板文件
技术分享图片
 1 import { Component, OnInit, Output, EventEmitter } from @angular/core;
 2 
 3 
 4 @Component({
 5   selector: app-child,
 6   templateUrl: ./child.component.html,
 7   styleUrls: [./child.component.sass]
 8 })
 9 export class ChildComponent implements OnInit {
10 
11   @Output()
12   initEmit = new EventEmitter<string>();
13 
14   constructor() { }
15 
16   ngOnInit() {
17     this.initEmit.emit("子组件初始化成功");
18   }
19 }
子组件TS文件
技术分享图片
1 <p>
2   parent-and-child works!
3 </p>
4 <app-child (initEmit)="accept($event)"></app-child>
父组件模板文件
技术分享图片
 1 import { Component, OnInit, Output, EventEmitter } from @angular/core;
 2 
 3 @Component({
 4   selector: app-parent,
 5   templateUrl: ./parent-and-child.component.html,
 6   styleUrls: [./parent-and-child.component.sass]
 7 })
 8 export class ParentAndChildComponent implements OnInit {
 9 
10   constructor() { }
11 
12   ngOnInit() {
13     
14   }
15   accept(msg:string) {
16     alert(msg);
17   }
18 }
父组件TS文件

 

2.2没有直接关系的组件

2.2.1service

做一个全局单例的service,然后多个组件共享这个实例,当然就可以共享其中的成员,来进行通讯

技术分享图片

                                   图片来源:大漠穷秋

具体代码如下

技术分享图片
1 import { Component, Injectable, EventEmitter } from @angular/core;
2 @Injectable()
3 export class myService {
4   public info:string = ‘‘;
5   constructor() {}
6 }
service文件

在app.module.ts文件的providers里添加这个服务

技术分享图片
1 <p>child1 work</p>
2 
3 <button (click)="showInfo()"></button>
组件1的模板文件
技术分享图片
 1 import { Component, OnInit} from @angular/core;
 2 import { myService } from ../../../service/myService..service;
 3 
 4 
 5 @Component({
 6   selector: app-child,
 7   templateUrl: ./child1.component.html,
 8   styleUrls: [./child1.component.sass]
 9 })
10 export class Child1Component implements OnInit {
11 
12   constructor(
13     public service: myService
14   ) { }
15 
16   ngOnInit() {
17     
18   }
19   showInfo() {
20     alert(this.service.info);
21   }
22 }
组件1的TS文件
技术分享图片
1 <p>
2   child2 works!
3 </p>
4 <button (click)="changeInfo()"></button>
组件2的模板文件
技术分享图片
 1 import { Component, OnInit} from @angular/core;
 2 import { myService } from ../../service/myService..service;
 3 
 4 @Component({
 5   selector: app-child2,
 6   templateUrl: ./child2.component.html,
 7   styleUrls: [./child2.component.sass]
 8 })
 9 export class Child2Component implements OnInit {
10 
11   constructor(
12     public service: myService
13   ) { }
14 
15   ngOnInit() {
16 
17   }
18   changeInfo() {
19     this.service.info = this.service.info + "1234";
20   }
21 }
组件2的TS文件

 

2.2.2路由传值

对于2个不同路由的组件,我们也可以通过路由传递信息

假设2个路由分别为~/home,~/about

2.2.2.1传递一个值

 假如从~/home路由向~/about路由传递一个字符串或数字

 1先把~/about的路由地址改为~/about/:id

 2在/home写上路由跳转且传值的连接

1 <button [routerLink]="[‘/about‘,1]">跳转</button>
2 <button [routerLink]="[‘/about‘,"home"]">跳转</button>

 3在跳至的页面~/about接受传入的值

1   id: string = ‘‘;
2 
3   ngOnInit() {
4     //获取传入的值
5     this.id = this.route.snapshot.params[id];
6   }

 

2.2.2.2传递一个对象

类似于上述的传递一个值,但是不需要再路由末尾加上/:id

代码也有些不同

 1 <button [routerLink]="[‘/about‘]" 2 [queryParams]="{id:12,status:true}">跳转</button> 

接受传入的对象

1   id: number = 0;
2   status: boolean = false;
3   ngOnInit() {
4     this.route.queryParams
5       .subscribe((params: Params) => {
6         this.id = params[id];
7         this.status = params[status];
8       })
9   }

 

3通用方式实现通讯

3.1localstorage处理

在angular中也可以使用本地存储这种比较通用的方式在组件间通讯,但本地存储有下列弊端:

1存储空间有限

2只能存储字符串

技术分享图片

                                       图片来源:大漠穷秋

具体的实现代码如下

技术分享图片
 1 import { Component, OnInit } from @angular/core;
 2 
 3 @Component({
 4   selector: app-child1,
 5   templateUrl: ./child1.component.html,
 6   styleUrls: [./child1.component.sass]
 7 })
 8 export class Child1Component implements OnInit {
 9 
10   constructor() { }
11 
12   ngOnInit() {
13 
14   }
15 
16    setData(){
17     window.localStorage.setItem("test", JSON.stringify({ key: test, value: 1 }));
18   }
19 }
组件1的Ts的文件
技术分享图片
 1 import { Component, OnInit } from @angular/core;
 2 
 3 @Component({
 4   selector: app-child2,
 5   templateUrl: ./child2.component.html,
 6   styleUrls: [./child2.component.sass]
 7 })
 8 export class Child2Component implements OnInit {
 9 
10   constructor() { }
11 
12   ngOnInit() {
13 
14   }
15 
16    getData() {
17     var json = window.localStorage.getItem("test");
18     var obj = JSON.parse(json);
19     console.log(obj.key);
20     console.log(obj.value);
21   }
22 }
23 
24 
25  
26 
27  
28 
29  
组件2的TS文件

 

服务端处理

也可以在服务端来处理组件间的通讯问题,这是一个思路,但是已经脱离讨论的主题,就不赘述

 

4结语

本文是对angular里组件间的通讯做一个简单的系统的归纳,其中很多细节可以自成一篇文章的,出于篇幅和能力的原因,文章中没有详尽描述

对于文章中的错误或不足之处,欢迎指正

 

学习参考资源(大漠穷秋):http://www.ngfans.net/topic/12/post/2

出自:博客园-半路独行

原文地址:https://www.cnblogs.com/banluduxing/p/9290569.html

本文出自于http://www.cnblogs.com/banluduxing 转载请注明出处。

 

Angular6.x学习笔记——组件详解之组件通讯

原文:https://www.cnblogs.com/banluduxing/p/9290569.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!