如何使用ngrx和效果订阅动作成功回调

hap*_*400 21 ngrx angular

我正在尝试做一些简单的事情 - 在一些实体保存后(使用http请求)我想导航回列表路由.问题是:如何订阅成功动作(或者可能是减速器或效果?)

这是我的行为代码:

static SAVE_POST = '[POST] Save POST';
savePOST(Post): Action {
    return {
        type: PostActions.SAVE_POST,
        payload: Post
    };
}

static SAVE_POST_SUCCESS = '[POST] Save POST Success';
savePOSTSuccess(Post): Action {
    console.log('action: savePostSuccess')
    return {
        type: PostActions.SAVE_POST_SUCCESS,
        payload:Post
    };
}
Run Code Online (Sandbox Code Playgroud)

我正在使用效果:

   @Effect() savePost$ = this.update$
    .ofType(PostActions.SAVE_POST)
    .map(action => action.payload)
    .switchMap(post => this.svc.savePost(post))
    .map(post => this.postActions.savePOSTSuccess(post));
Run Code Online (Sandbox Code Playgroud)

减速器:

const initialState: PostListState = [];

export default function (state = initialState, action: Action): PostListState {
    switch (action.type) {
        case PostActions.LOAD_POST_SUCCESS: {
            return action.payload;
        }
        case PostActions.SAVE_POST_SUCCESS: {
            console.log('SavePOST SUCCESS',action.payload)
            let index = _.findIndex(state, {_id: action.payload._id});
            if (index >= 0) {
                return [
                    ...state.slice(0, index),
                    action.payload,
                    ...state.slice(index + 1)
                ];
            }
            return state;
        }
        default: {
            return state;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的组件中,我想订阅成功回调:

   handlePostUpdated($event) {
     this.post = this.code;
     let _post: Post = Object.assign({}, { _id: this.id, name: this.name, text: this.post });
     this.store.dispatch(this.postActions.savePOST(_post)); //not have "subscribe" method

  }
Run Code Online (Sandbox Code Playgroud)

感谢帮助

ols*_*lsn 46

您也可以订阅组件中的操作:

[...]
import { Actions } from '@ngrx/effects';
[...]

@Component(...)
class SomeComponent implements OnDestroy {
    destroyed$ = new Subject<boolean>();

    constructor(updates$: Actions) {
        updates$
            .ofType(PostActions.SAVE_POST_SUCCESS)
            .takeUntil(this.destroyed$)
            .do(() => /* hooray, success, show notification alert ect.. */)
            .subscribe();
    }

    ngOnDestroy() {
        this.destroyed$.next(true);
        this.destroyed$.complete();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 与`takeUntil(...)`结合使用的`destroyed $`是一种自动取消订阅的模式,因此您无需跟踪订阅. (3认同)
  • 总是有很多方法,但是如果您只想显示一条小通知,即表示保存成功,则这种方法是“最干净的”恕我直言,因为这是一次性事件,因此不应全部通过商店的方式 (2认同)

AJT*_*T82 28

基于此:https://netbasal.com/listening-for-actions-in-ngrx-store-a699206d2210进行了一些小修改,因为ngrx 4已经没有Dispatcher了,但是ActionsSubject:

import { ActionsSubject } from '@ngrx/store';
import { ofType } from "@ngrx/effects";

subsc = new Subcription();

constructor(private actionsSubj: ActionsSubject, ....) { 
  this.subsc = actionsSubject.pipe(
     ofType('SAVE_POST_SUCCESS')
  ).subscribe(data => {
     // do something...
  });
}

ngOnDestroy() {
  this.subsc.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)

  • 截至2018年8月,这应该是公认的答案 - 接受的答案现在已被弃用 - 使用这种更现代的方法 (3认同)
  • 这与使用actions $:Actions然后执行.ofType('SAVE_POST_SUCCESS')`有什么不同吗?我注意到这种方法会更快地触发它,然后是ActionSubject。这是否意味着只有在减速机运行后才会触发? (2认同)
  • @YehiaA.Salam,正如它的名字一样,订阅。如果我们不取消订阅,就会出现内存泄漏,即可观察的“actionSubject”保持打开状态。 (2认同)
  • 它从来都不是其中的一部分。它来自`rxjs`:`import { Subscription } from 'rxjs'`。文档:https://rxjs-dev.firebaseapp.com/guide/subscription :) (2认同)