摘要:采用觀察者模式,通過其訂閱發布機制,可以簡化數據傳輸的過程,使每個模塊獨立起來,我們的模塊能更加專注于業務代碼的編寫。
場景
如上圖,在一個歌曲詳情模塊,假設有2個子模塊,歌曲模塊和評論模塊。
在歌曲模塊和評論模塊中都有評論數量這個屬性,當用戶在評論模塊發布了一條評論后,評論模塊和歌曲模塊的數量要同步更新。
評論模塊的數量很好更新,歌曲模塊的評論數量怎么同步更新呢?
下面介紹幾種實現方法。
1. 雙向綁定實現
思路:
在AppComponent將評論數量count作為輸入參數(@Input)傳遞給CommentComponent和MusicComponent,當AppComponent中的評論數量改變時,MucisComponent中的評論數量也會同時改變。
當CommentComponent更新評論數量count時,通過輸出參數(@Output)更新AppComponent中的評論數量count,MusicComponent中的評論數量count就會跟著改變了。
AppComponent
import { Component } from "@angular/core"; @Component({ selector: "app-root", template: `` }) export class AppComponent { count:number = 0; constructor() { } }
MusicComponent
import { Component, Input } from "@angular/core"; @Component({ selector: "app-music", template: ``, styleUrls: ["./music.component.css"] }) export class MusicComponent{ // 評論數 @Input() count:number; constructor() { } }歌曲模塊
評論數:{{ count }}
CommentComponent
import { Component, EventEmitter, Input, Output } from "@angular/core"; @Component({ selector: "app-comment", template: `` }) export class CommentComponent { // 評論數 @Input() count:number = 0; // 評論數改變事件 @Output() countChange:EventEmitter評論
評論數:{{ count }}
- {{ item }}
= new EventEmitter (); // 評論列表 comments:string [] = []; constructor() { } // 發送評論 send(content) { if (content.value) { this.comments.push(content.value); this.count++; this.countChange.emit(this.count); } } }
2. 觀察者模式實現
思路
構建一個觀察者對象,觀察者對象擁有注冊(regist),發布(fire),移除(remove)三個方法。在angular2中可以通過依賴注入注入到CommentComponent和MusicComponent。
在MusicComponent中注冊(regist),‘count’ 事件。
當用戶發送評論時,在CommentComponent中發布(fire),‘count’事件。
構造觀察者對象
import { Injectable } from "@angular/core"; @Injectable() export class ObserverService { /** * 消息隊列 * 用數組保存每一種消息的事件隊列, * eventList["count"] = [] * 注冊消息時將事件回調函數push到事件隊列 * eventList["count"].push(fn) * 發布消息時依次執行消息隊列中的每一個回調函數 * for(let fn of eventList["count"]) { * fn(data); * } */ eventList = {}; constructor() { } /** * 發布消息 * @param name 消息名 * @param data 消息數據 */ fire(name:string, data:any) { if (this.eventList[name]) { const fns = this.eventList[name]; for(let fn of fns) { fn(data); } } } /** * 注冊消息 * @param name * @param fn */ regist(name:string, fn:any) { if (typeof fn === "function") { const fns = this.eventList[name]; if (fns) { fns.push(fn); } else { this.eventList[name] = [fn]; } } } /** * 移除消息 * @param name * @param fn */ remove(name:string, fn:any) { const fns = this.eventList[name]; if (fns) { if ( fn ) { let i; for(i = 0; i < fns.length; i++) { if (fns[i] === fn) { break; } } if (i < fns.length) { fns.splice(i, 1); } } else { fns.length = 0; } } } }
AppComponent
import { Component } from "@angular/core"; @Component({ selector: "app-root", template: `` }) export class AppComponent { constructor() { } }
MusicComponent
import { ObserverService } from "../service/observer.service"; import { Component, Input } from "@angular/core"; @Component({ selector: "app-music", template: ``, styleUrls: ["./music.component.css"] }) export class MusicComponent{ // 評論數 count:number; constructor(private observiceService:ObserverService) { // 注冊消息 this.observiceService.regist("count", count => this.count = count); } }歌曲模塊
評論數:{{ count }}
CommentComponent
import { ObserverService } from "../service/observer.service.2"; import { Component, EventEmitter, Input, Output } from "@angular/core"; @Component({ selector: "app-comment", template: `` }) export class CommentComponent { // 評論數 count:number = 0; // 評論列表 comments:string [] = []; constructor(private observiceService:ObserverService) { } send(content) { if (content.value) { this.comments.push(content.value); this.count++; // 發布消息 this.observiceService.fire("count", this.count); } } }評論
評論數:{{ count }}
- {{ item }}
3. 使用Rxjs中的Subject實現
subject參考
SubjectService
import { Observable, Subject } from "rxjs/Rx";
import { Injectable } from "@angular/core";
@Injectable()
export class SubjectService {
count:number = 0; comment:Subject; constructor() { this.comment = new Subject (); }
}
AppComponent
import { Component } from "@angular/core"; @Component({ selector: "app-root", template: `` }) export class AppComponent { constructor() { } }
MusicComponent
import { SubjectService } from "../service/subject.service"; import { Component, Input } from "@angular/core"; @Component({ selector: "app-music", template: ``, styleUrls: ["./music.component.css"] }) export class MusicComponent{ // 評論數 count:number; constructor(private subjectService:SubjectService) { // 注冊消息 this.subjectService.comment.subscribe(count => this.count = count); } }歌曲模塊
評論數:{{ count }}
4. 小結
在使用雙向綁定進行多個的模塊間的數據傳輸時,可以看到,當需要傳遞某個變量時,我們需要在每個模塊中構造對應的@Input和@Output,借助父模塊來進行傳遞數據,過程比較繁瑣。
AppComponent
CommentComponent
MusicComponent
采用觀察者模式,通過其訂閱發布機制,可以簡化數據傳輸的過程,使每個模塊獨立起來,我們的模塊能更加專注于業務代碼的編寫。
AppComponent
MusicComponent
CommentComponent
借助Rxjs的Subject,我們能很方便的實現同樣的功能。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88700.html
摘要:設計模式的類別設計模式一共分為種類型,共種。屬于結構型的設計模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。問題描述了應該在何時使用設計模式。解決方案描述了設計的組成成分,它們之間的相互關系及各自的職責和協作方式。 設計模式概述 1. 設計模式是什么 我們在平時編寫代碼的過程中,會遇到各種各樣的問題,細想一下很多問題的解決思路大致一樣的,這時候你就可以把解決問題的思路整...
摘要:設計模式的分類經典應用框架中常見的設計模式分為三類創建型模式對類的實例化過程的抽象。對象的結構模式是動態的。對象的行為模式則使用對象的聚合來分配行為。設計模式是個好東西,以后肯定還要進一步的學習,并且在項目中多實踐,提升自己的設計能力。 什么是設計模式? Christopher Alexander?說過:每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題的解決方案的核心。這樣...
摘要:我們今天也來做一個萬能遙控器設計模式適配器模式將一個類的接口轉換成客戶希望的另外一個接口。今天要介紹的仍然是創建型設計模式的一種建造者模式。設計模式的理論知識固然重要,但 計算機程序的思維邏輯 (54) - 剖析 Collections - 設計模式 上節我們提到,類 Collections 中大概有兩類功能,第一類是對容器接口對象進行操作,第二類是返回一個容器接口對象,上節我們介紹了...
摘要:當云計算成為一種公共服務,社會創新的成本也由此大幅降低。在全球市場,中國云計算公司仍處于追趕狀態,今后有望借助服務一帶一路的機遇加速發展。數據來源:《省級政府網上政務服務能力調查評估報告(2018)》、阿里巴巴、騰訊制圖:郭 祥習近平總書記在致首屆數字中國建設峰會的賀信中指出,當今世界,信息技術創新日新月異,數字化、網絡化、智能化深入發展,在推動經濟社會發展、促進國家治理體系和治理能力現代化...
閱讀 3564·2023-04-26 00:05
閱讀 954·2021-11-11 16:55
閱讀 3523·2021-09-26 09:46
閱讀 3517·2019-08-30 15:56
閱讀 909·2019-08-30 15:55
閱讀 2934·2019-08-30 15:53
閱讀 1940·2019-08-29 17:11
閱讀 814·2019-08-29 16:52