使用Redux和ngrx构建更好的Angular2应用(四)
使用Redux和ngrx构建更好的Angular2应用(四)
我是钟钟 发表于4个月前
使用Redux和ngrx构建更好的Angular2应用(四)
  1. 发表于 4个月前
  2. 阅读 423
  3. 收藏 10
  4. 点赞 1
  5. 评论 1
摘要: redux,angular2
我的Angular2项目:http://git.oschina.net/zt_zhong/CodeBe 原文地址:http://onehungrymind.com/build-better-angular-2-application-redux-ngrx/

调用所有服务

首先,将Http和Headers从angular2/http模块导入到应用中,准备Http调用。 import {Http, Headers} from 'angular2/http'; 然后,我们定义一个BASE_URL常量,所以我们只需要键入一次,我们也将创建一个HEADER常量来告诉我们服务器我们如何与它进行通信。这可能不是必需的,这取决于你正在使用的后端,但是要让json-server工作,我不得不添加它。 const BASE_URL = 'http://localhost:3000/items/'; const HEADER = { headers: new Headers({ 'Content-Type': 'application/json' }) }; 我们修改ItemsService的构造器,将Http对象作为类的一个http属性注入进来。 constructor(private http: Http, private store: Store<AppStore>) { this.items = store.select('items'); } 从这里,让我们修改我们的CRUD方法来处理远程服务器调用,从loadItems开始。我们正在调用this.http.get(BASE_URL)来获取我们的远程items,并且因为Http返回一个observable,所以我们可以通过额外的操作来管理结果。我们将调用map来解析返回结果然后再调用map来创建一个对象然后分发给对应的reducer。map操作的返回结果是一个Observable对象,因为每一个结果都是通过它来操作序列的。为了“捆绑”序列,我们将订阅它,然后通过调度我们的转换结果将控制权交给我们的reducer。 loadItems() { // Retrieves the items collection, parses the JSON, creates an event with the JSON as a payload, // and dispatches that event this.http.get(BASE_URL) .map(res => res.json()) .map(payload => ({ type: 'ADD_ITEMS', payload })) .subscribe(action => this.store.dispatch(action)); } 当我们更新createItem时,我们将会遵循类似的模式。唯一的不同是,我们使用http.post和格式化了的请求体以及HEADER常量来访问服务器。一旦我们有了返回结果,我们将所有内容映射到我们可以在我们的订阅方法中发送的对象。 createItem(item: Item) { this.http.post(BASE_URL, JSON.stringify(item), HEADER) .map(res => res.json()) .map(payload => ({ type: 'CREATE_ITEM', payload })) .subscribe(action => this.store.dispatch(action)); } 更新和删除有点简单,因为我们不依赖于从服务器返回的对象。我们只需要关注操作是否成功。因为这些,我们将使用http.put和http.delete,然后跳过返回结果的映射这一步。我们可以从subscribe中分发一个动作到reducer。看下面的代码: updateItem(item: Item) { this.http.put(`${BASE_URL}${item.id}`, JSON.stringify(item), HEADER) .subscribe(action => this.store.dispatch({ type: 'UPDATE_ITEM', payload: item })); } deleteItem(item: Item) { this.http.delete(`${BASE_URL}${item.id}`) .subscribe(action => this.store.dispatch({ type: 'DELETE_ITEM', payload: item })); }

测试

redux的最重要的方面之一是测试reducer是非常容易的,因为它们是具有明确意图的纯函数。关于我们的应用,包含可测试逻辑的表面积已大大减少。当我写这些的时候我并没有想搞笑,但事后看来,那就是!

配置

我不会进入整个测试工具,而是快速浏览我们的测试规范。我们需要做的第一步是导入items和selectedItems以及从angular2/testing中导入it,describe和expect。稍等。这不是Jasmine的方法吗??是的,Angular2默认使用的就是Jasmine。 import {items, selectedItem} from './items'; import { it, describe, expect } from 'angular2/testing'; 作为参考,我们的规格的骨架看起来像这样。 describe('Items', () => { describe('selectedItem store', () => { it('returns null by default', () => {}); it('SELECT_ITEM returns the provided payload', () => {}); }); describe('items store', () => { let initialState = [ { id: 0, name: 'First Item' }, { id: 1, name: 'Second Item' } ]; it('returns an empty array by default', () => {}); it('ADD_ITEMS', () => {}); it('CREATE_ITEM', () => {}); it('UPDATE_ITEM', () => {}); it('DELETE_ITEM', () => {}); }); }); 测试真的很容易写,因为我们从一个初始状态开始,当我们向我们的reducer发送一个动作时,我们知道我们应该得到什么。我们知道,如果我们发出ADD_ITEMS的动作,我们将收回我们在有效载荷(payload)中的任何内容,我们在下面的断言中看到。 it('ADD_ITEMS', () => { let payload = initialState, stateItems = items([], {type: 'ADD_ITEMS', payload: payload}); // Don't forget to include an initial state expect(stateItems).toEqual(payload); }); 如果我们使用CREATE_ITEM的动作类型调用items reducer,那么我们预期结果将是初始数组加上新的记录。 it('CREATE_ITEM', () => { let payload = {id: 2, name: 'added item'}, result = [...initialState, payload], stateItems = items(initialState, {type: 'CREATE_ITEM', payload: payload}); expect(stateItems).toEqual(result); }); 我们可以轻松地阐述剩下的两个reducer的方法的预期结果,然后为我们写下如下所示的断言。 it('UPDATE_ITEM', () => { let payload = { id: 1, name: 'Updated Item' }, result = [ initialState[0], { id: 1, name: 'Updated Item' } ], stateItems = items(initialState, {type: 'UPDATE_ITEM', payload: payload}); expect(stateItems).toEqual(result); }); it('DELETE_ITEM', () => { let payload = { id: 0 }, result = [ initialState[1] ], stateItems = items(initialState, {type: 'DELETE_ITEM', payload: payload}); expect(stateItems).toEqual(result); });

回顾

我们已经在本文中讲了很多,如果你已经做到了这一点! 让我们快速回顾一下我们所做的工作。
  • redux的核心特性是统一的状态,事件向上以及自顶向下的状态流。
  • @ngrx/store实现使用observables可以让我们使用异步管道填充我们的模板。
  • 3.我们创建了reducers,它接收一个动作和一个状态,并且返回一个新的状态对象。 4.我们的reducer功能必须是纯粹的,所以我们看到了如何创建它们而不会使我们的集合改变。 5.一个store是一个基本的键值对map,和一些处理事件和发射状态的机制。 6.通过使用store.emit来广播事件。 7.我们使用store.select来订阅数据。 8.使用表单创建本地副本以避免更高级别的改变。 9.使用异步调用,我们通过Observable序列传递我们的结果,然后在完成时将该事件发送到reducer。 10.reducer非常易于测试,因为方法非常纯净。 通过@ngrx/store学习redux一直是我在一段时间内感受到的那种“新程序员”的感觉。非常好玩,对不对?? 举个例子,玩弄一下,思考如何在日常项目中使用这种方法。
    标签: angualr2 ng2 ngrx redux
    1. 打赏
    2. 点赞
    3. 收藏
    4. 分享
    共有 人打赏支持
    粉丝 38
    博文 25
    码字总数 23424
    作品 1
    评论 (1)
    ×
    我是钟钟
    如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
    * 金额(元)
    ¥1 ¥5 ¥10 ¥20 其他金额
    打赏人
    留言
    * 支付类型
    微信扫码支付
    打赏金额:
    已支付成功
    打赏金额:
    利发国际官方网