使用Angular2建立一个可扩展单页应用
本文主要讲解使用Angular2.JS、RxJS和ngrx等技术如何构建前端一个可伸缩扩展的单页应用。该应用基于后端RESTful API构建,当前用户之间可以通过P2P创建通讯连接,也能够和应用服务器实时通信,这里将出现多个通讯协议:HTTP, WebSocket, UDP via WebRTC。对应不同的数据包格式:
- 基于HTTP/Websocket的 JSON格式
- WebSocket的JSON-RPC
- WebRTC 或 WebSocket的BERT 或BERT-RTC
BERT 协议能够有效创建P2P通讯,实现二进制数据传输,入图片或任何使用文本方式传输不够效率的数据形式。RxJS是进行所有异步事件处理的总线,使用同样的通讯通道可以混合多个数据流格式,能够进行过滤filter,传输,处理等等。
模块设计
由于该项目有多个可变数据源,用户操作是一个,来自后端的推送通知还有使用WebRTC用户之间的P2P通讯消息,为了有一个可预期的状态管理,需要统一这些可变的数据源与可变状态,有许多模式可以帮助我们实现这点,Redux是最流行的一种。下图是基于Redux对这个应用前端进行架构分层的组件图:
UI组件是用户直接操作的界面层,facade是UI的代表层,是一系列提供简化接口的对象,主要目标是允许我们能够触发应用的Action操作 ,从而调用Redux的reducer方法,将Action操作分发到异步服务层,因此类似dispatcher分发层。在facade层我们还会抽象我们的业务模型,假设我们我们开发一个Game,那么在GameComponent中我们使用GameModel抽象代表可变的状态。
技术选型
虽然React的react-router 支持懒加载,但是React生态系统还没有缺乏对象概念的依赖注入,而Angular 2的强项在于依赖注入和Webworker支持。
因此技术选型如下:
本应用开发的很多思想和理念都可以应用到其他框架比如React实现。
应用需求
作为我们演示应用,这个应用主要是一个小游戏,让你能够练习打字,给出一段文字,衡量你跟着打字打出来要用多长时间,可以几个用户一起比赛:
案例源码。
模型定义
Gamemodel是代表可变的状态,代码如下:
@Injectable()
export class GameModel extends Model {
games$: Observable<string>;
game$: Observable<string>;
constructor(protected _store: Store<any>,
@Optional() @Inject(AsyncService) _services: AsyncService[]) {
super(_services || []);
this.games$ = this._store.select('games');
this.game$ = this._store.select('game');
}
startGame() {
this._store.dispatch(GameActions.startGame());
}
onProgress(text: string) {
this.performAsyncAction(GameActions.gameProgress(text, new Date()))
.subscribe(() => {
// Do nothing, we're all good
}, (data: any) => {
if (data.invalidGame)
this._store.dispatch(GameActions.invalidateGame());
});
}
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
GameModel
能够被startGame
action调用以开始一个游戏,, 能够被rameActions
action 创建,比如:
this._store.dispatch(GameActions.startGame());
使用指定的Action调用dispatch方法会激活所有注册到存储中的reducer,通过使用传递的action作为一个参数会产生一个新的存储,存储将会通过game的被观察者发送到相应视图,下面结构:
原文:Scalable Single-Page Application Architecture