[Angular2] @Ngrx/store and @Ngrx/effects learning note

Just sharing the learning experience related to @ngrx/store and @ngrx/effects.

In my personal opinion, I fell there are tow different types of coding style by using

  1. @ngrx/store only

  2. @ngrx/store + @ngrx/effects

So How we do with only ngrx/store?

Controller:

 deleteItem(item: Item) {
    this.subs[‘deleteItem‘] = this.itemsService.deleteItem(item)
      .subscribe(
        (res) => {
          console.log("Delete Item success", JSON.stringify(res, null, 2))
          this.resetItem();
        },
        (err) => alert("error")
      );
  }

Service:

export class ItemsService {
  items$: Observable<Item[]> = this.store.select(‘items‘);

  constructor(
    private http: Http,
    private store: Store<AppStore>,
    private actions: ItemsActions
  ) {}
  deleteItem(item: Item) {
    return this.http.delete(`${BASE_URL}${item.id}`)
      .do(action => this.store.dispatch({ type: DELETE_ITEM, payload: item }));
  }

Reducer:

    case DELETE_ITEM:
      return state.filter(item => {
        return item[comparator] !== action.payload[comparator];
      });

As you can see, the working flow is like that:

  1. Form controller we call the Service to delete the item

  2. Service do the http call to remove the item

  3. Then we have ‘.do()‘ method to create side effect, call dispatch

  4. Since the return from Service is Observable, we subscribe form the controller.

  5. Inside successfully handler, we can do any other ui side effect.

ngrx/store + ngrx/effects:

Controller:

  deleteWidget(widget: Widget) {
    this.store.dispatch({type: DELETE_WIDGET, payload: widget});
  }

Service:

  deleteWidget(widget: Widget) {
    return this.http.delete(`${BASE_URL}${widget.id}`);
  }

Effect:

  @Effect() delete$: Observable<Action> = this.actions$
    .ofType(DELETE_WIDGET)
    .map(action => action.payload)
    .switchMap((widget)=>{
      return this.widgetsService.deleteWidget(widget)
                .map(success => console.log("success"))
                .catch(() => of("error")) // catch expect to get an observable back
    });

Reducer:

    case DELETE_WIDGET:
      return state.filter(widget => {
        return widget[comparator] !== action.payload[comparator];
      });

So the work flow for ngrx/store + ngrx/effects:

  1. From the controller, we just dispatch the action.

  2. Effect listening the actions that dispatched, and trigger ‘ofType‘ the same is dispatched action from controller.

  3. Inside effect, we call service to delete the widget.

  4. If http request is success, we actually can dispatch another UI action that will do the UI rendering.

  5. If http reuqest is faild, we catch it and you actually can dispatch another UI action that will show the error in UI.

Github

Summary:

By using only ngrx/store, we are still using the coding style we get used to, like controller talking to the service, after service done its job, return back to controller, let controller do whatever necessary.

By using ngrx/store + ngrx/effects, we are actullay walking into RxJS + Redux world, everything goes reactive, everything should have a reducer even it is UI rendering stuff.

I am not sure which way is better. My point is I am using Redux partten, take advantage of RxJS to help me handle state management esailer. But I don‘t know to overkill, everything conver to Observable and reducers style is way to far from the starting point -- state management.

时间: 2024-10-17 15:23:16

[Angular2] @Ngrx/store and @Ngrx/effects learning note的相关文章

[Angular 2] ngrx/store

@ngrx/store builds on the concepts made popular by Redux and supercharges it with the backing of RxJS. The result is a tool and philosophy that will transform the way you approach state management in your Angular 2 applications. This lesson takes an

NgRx/Store 4 + Angular 5使用教程

这篇文章将会示范如何使用NgRx/Store 4和Angular5.@ngrx/store是基于RxJS的状态管理库,其灵感来源于Redux.在NgRx中,状态是由一个包含action和reducer的函数的映射组成的.Reducer函数经由action的分发以及当前或初始的状态而被调用,最后由reducer返回一个不可变的状态.你可以在@ngrx/store中找到我们将在下面的例子中讨论到的相关的API. Action: Action是状态的改变.它描述了某个事件的发生,但是没有指定应用的状态

Kali linux learning note

from:http://blog.sina.com.cn/s/blog_40983e5e0101dhz0.html 因为kali linux基于debian 7,当然要把这台Acer 4736z原有的debian 7删掉装kali啦,哈哈,这下不必为了BT5装虚拟机了,对于本子里60G的SSD来说还是好事一桩.要把kali当做桌面使用,就必须给kali添加一些软件,修改一些设置才好用,下面记录一下备忘,随时更新. 安装方法,官方文档,硬盘安装Kali Linux 把apt源设为官方提供的国内镜像

Learning Note: SQL Server VS Oracle–Database architecture

http://www.sqlpanda.com/2013/07/learning-note-sql-server-vs.html This is my learning note base on the "SQL Server Essentials for Oracle DBAs Jump Start" . DATA BLOCK/EXTEND AND SEGMENT image: http://lh5.ggpht.com/-FxEKn7CCNd0/UetkOxZ6igI/AAAAAAA

shell learning note

shell learning note MAIN="/usr/local/" # 变量大写 STATUS="$MAIN/status" # 美元符加字符串是引用变量值,而美元符加数字表示命令行参数 echo "some words" >>$STATUS/log.log echo "test.sh start at `date '+%m/%d %H:%M:%S'`" >>$STATUS/log.log c

Python 基础 - Day 5 Learning Note - 模块 之 标准库:ConfigParser (10)

configparser模块介绍 用于生成和修改常见的配置文档(configuration file), 配置文件格式 用户配置文件就是在用户登录电脑时,或是用户在使用软件时,软件系统为用户所要加载所需环境的设置和文件的集合.它包括所有用户专用的配置设置,如程序项目.屏幕颜色.网络连接.打印机连接.鼠标设置及窗口的大小和位置等.一般格式包括ini,cfg,xml, config等. 配置文件的格式如下 [DEFAULT] ServerAliveInterval = 45 Compression

2014/09/30 Learning Note

Vbird Linux: Vim Learning: http://linux.vbird.org/linux_basic/0310vi.php Bash Shell: http://linux.vbird.org/linux_basic/0320bash.php Key words of reminder: /etc/passwd history alias [Tab] Wildcard type ---builtin commands \[Enter] echo $variable

Python 基础 - Day 5 Learning Note - 模块 之 标准库:time (1)

时间的表示方式 1. 间戳 timestamp:  从1970年1月1日 00:00:00 开始按秒计算的偏移量,以float数据类型呈现. 返回时间戳的函数有: time() , clock() 等. 2. sruct_time 元祖方式: 返回struct_time元祖的函数包括 gmtime(), localtime(), strptim(). 返回的元祖包括以下9个元素. 索引 INDEX 属性 ATTRIBUTE 值 VALUES 0 tm_year  比如2011 1 tm_mon

Python 基础 - Day 4 Learning Note - 模块 - Json &amp; Pickle

Json和Pickle的区别 在python的序列化的两个模块中,json模块是用于字符串和python数据类型间进行转换:另一个pickle模块,是用于python特有的类型(所有数据类型和python的数据类型间进行转换.json是可以在不同语言之间交换数据的,而pickle只在python之间使用.json只能序列化最基本的数据类型,json只能把常用的数据类型序列化(列表.字典.列表.字符串.数字.),比如日期格式.类对象!josn就不行了.而pickle可以序列化所有的数据类型,包括类