對於一個應用來講,獲取數據的方法能夠有不少,好比:Ajax, Websockets, LocalStorage, Indexdb, Service Workers,可是如何整合多種數據源、如何避免BUG、如何提升可維護性、如何提高應用的速度,這些卻又是須要解決的問題。MVC是經典的Web應用開發模式,但對於客戶端應用卻不太適合。針對這點又出現了一些其它的模式,好比MVW(Model-View-Whatever)雙向綁定模式、Flux、Observables等。編程
Angular1採用雙向綁定的方式,但到了Angular4,對於數據結構的選擇就很是靈活了,能夠根據應用的場景自行決定。數組
1、Observables and RxJS數據結構
Observables方式屬於響應式編程(ReactiveProgramming),數據流是異步傳輸的,採用Observables方式須要導入RxJS庫。接下來經過一個聊天應用的實現瞭解Observables和RxJS。異步
a) 聊天應用總體來講包含三部分,聊天列表、對話框、未讀消息。相應地有三個Model、三個service。service維護數據流,數據流傳輸model,組件訂閱數據流並渲染界面。socket
userModel包含is,name, avatarSrc三個屬性;學習
threadModel包含的屬性有id, lastMessage, name, avatarSrc;this
messageModel包含的屬性有 id, isRead, sentAt, anthor, text, thread.spa
b) UserService雙向綁定
建立的UsersService類須要標記爲@Injectable,便於以後的注入。server
import{ Subject, BehaviorSubject } from 'rxjs';
…
@Injectable()
exportclass UsersService {
currentUser: Subject<User> = newBehaviorSubject<User>(null);
public setCurrentUser(newUser: User): void {
this.currentUser.next(newUser);
}
}
currentUser是一個Subject 類型,接收了一個BehaviorSubject對象,Subject是可讀可寫的流,同時繼承了Observable和Observer。通常來講消息發送到流後,若是沒有被接收就會丟失,但可以使用BehaviorSubject避免這個問題,BehaviorSubject會保存最後一次的值。
setCurrentUser()會經過Subject.next()將新的值送入流中。
c) MessageService
MessageService是這個應用的核心,全部的消息流都會通過這個Service。MessageService首先會包含三個「數據管理流」:newMessage發送新消息、messages發送最近消息的數組、update更新messages流。
update更新messages流時,採用操做流模式(Operation Stream Pattern)。
interfaceIMessagesOperation extends Function {
(messages: Message[]): Message[];
}
exportclass MessagesService {
updates: Subject<any> = newSubject<any>();
constructor() {
this.messages = this.updates
.scan((messages: Message[],
operation: IMessagesOperation)=> {
return operation(messages);
},
initialMessages).
.publishReplay(1)
.refCount();
傳入updates流中的是方法,這個方法的輸入和輸出都是message數組,爲此定義接口IMessagesOperation,而後使用Subject.scan()。
流默認是不共享的,一次讀取後流中的數據就會消失,但這個應用中很多地方須要屢次讀取流,好比最近消息,因此使用了publishReplay和refCount方法。publishReplay設置流可在多個訂閱者間共享,並可設置對新加入的訂閱者的滯後值。
學習資料:The Complete Book on Angular by Nate Murray, Felipe Coury, AriLerner , Carlos Taborda