angular6.x系列的學習筆記記錄,仍在不斷完善中,學習地址:
系列目錄
(1)組件詳解之模板語法
(2)組件詳解之組件通訊
(3)內容投影, ViewChild和ContentChild
(4)指令
(5)路由
目錄章節
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 服務端
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 }

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 }
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 }

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 }
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 }

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 }
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 }
在app.module.ts文件的providers里添加這個服務

1 <p>child1 work</p> 2 3 <button (click)="showInfo()"></button>

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 <p> 2 child2 works! 3 </p> 4 <button (click)="changeInfo()"></button>

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.2.2路由傳值
對於2個不同路由的組件,我們也可以通過路由傳遞信息
假設2個路由分別為~/home,~/about
補充下述代碼路由的引用
1 import { Router } from '@angular/router'; 2 import { ActivatedRoute, Params } from '@angular/router'; 3 4 constructor( 5 private router: Router, 6 private route: ActivatedRoute, 7 ) { }
2.2.2.1傳遞一個值
假如從~/home路由向~/about路由傳遞一個字符串或數字
1先把~/about的路由地址改為~/about/:id, (:id 是一個路由參數的令牌(Token),比如~/home/42 這個URL中,“42”就是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 this.router.navigate(['/about'], { 2 queryParams: { 3 id: '1', 4 status: true 5 } 6 });
接受傳入的對象
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 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
3.2服務端處理
也可以在服務端來處理組件間的通訊問題,這是一個思路,但是已經脫離討論的主題,就不贅述
(終)
文檔信息
- 發表作者: 半路獨行
- 發表出處: 博客園
- 原文地址: https://www.cnblogs.com/banluduxing/p/9290569.html
- 版權信息:
本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。
感謝您的閱讀,如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕。本文歡迎各位轉載,但是轉載文章之后必須在文章頁面中給出作者和原文連接。