Angular4 actual combat (4) ngrx



Ngrx is the state management library of angular, which is the same as react Redux and is extended from redux. The example of this demonstration is to control the global loading animation display of HTTP request service through the state management of ngrx. As follows:
Angular4 actual combat (4) ngrx

Ngrx address:

Ngrx mainly has four modules, which are
ngrx/store, ngrx/effects, ngrx/router-store, ngrx/store-devtools
This instance uses ngrx 4. X version, because it is not associated with routing and has no complex behavior, only ngrx / store is used.

Similar to react reduce, the core of ngrx is to obtain the value (state) stored in the store through reducer, and change the median value (state) of the store through action. About action, reducer and store will not be introduced. For details, please refer to my previous article:…. Ngrx is essentially the same as react redux.

Define the action and reducer of loading

Angular4 actual combat (4) ngrx

Create the ngrx folder in the project, and create the action and reducer files under it. In the reducer folder, create index.ts as the summary of each reducer, which is convenient for later management and expansion.


// loading =>index.ts
import * as load from '../../action/loading';

const initialState = false;

export function reducer(state: boolean = initialState, action: load.Actions) {
  switch (action.type) {
    case load.SHOW_LOADING: {
      return true;

    case load.HIDE_LOADING: {
      return false;
    default: {
      return state;

Define the display and hide of loading animation.

// reducer=>index.ts 
// import {compose} from '@ngrx/core/compose';
// import {ActionReducer, combineReducers} from '@ngrx/store';
import * as loading from './loading';

export interface State {
  loading: boolean;

export const reducer = {
  loading: loading.reducer
// const developmentReducer: ActionReducer<any> = compose(storeFreeze, combineReducers)(reducers);
// const productionReducer: ActionReducer<any> = combineReducers(reducers);
// export function reducer(state: any, action: any) {
//   if (environment.production) {
//     return productionReducer(state, action);
//   } else {
//     return developmentReducer(state, action);
//   }
// }

The annotated code refers to the official example, which manages the state of ngrx through different environments. But I didn’t run this code successfully and didn’t report an error, but it didn’t work. I used a simple method to realize the summary of reducer.

Associated store

Ngrx Association injects storemodule into reducer in app.module.ts. Namely:

import {StoreModule} from '@ngrx/store';
import {reducer} from './ngrx/reducer';
  declarations: [
  imports: [
  providers: [],
  bootstrap: [AppComponent]
export class AppModule {



  selector: 'app-root',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `<router-outlet></router-outlet>
              <md-spinner class="loadPosition" *ngIf="showLoading$ | async"></md-spinner>`,
  styleUrls: ['./app.component.less'],

There are two points to note when writing the root component in loading.


Set up a change checking policy. Take the above code as an example. When onpush is set for the changedetectionstrategy, the component will not perform dirty checking all the time. Instead, the checking policy will be started only when the input property changes. Note here that the component will check only when the input object needs to change into a new object, Instead of just changing the value of an attribute, or increasing or decreasing the elements of an object.

For example{ name:j_ bleach}=>{ name:bleach }
Or when the input attribute is an array, [1,2,3] = > [1,2,3]. Push (4)
Neither of these two methods will trigger angular’s checking strategy(The premise is that changedetection: changedetectionstrategy. Onpush is set in the metadata

Based on this setting, if you want to start the policy, you need to return new objects and arrays.

For example, object. Assign ({}){ name:j_ bleach}, { name:bleach });
Or [… [1,2,3], 4] returns a new object.

In this case, a new value (usually a new object) is returned through the reducer, and a new value change will also cause component checking.
PS: the reason is that the value of each simple type will be stored in the new stack, while the object is different. The object has a reference to the same pointer (whether it can be similar to deep and shallow copy, here is a question mark);

A foreign article helps to understand:…
I don’t know if I need to go over the wall and post another article on SF…


Official explanation:
The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the async pipe marks the component to be checked for changes. When the component gets destroyed, the async pipe unsubscribes automatically to avoid potential memory leaks.

High school English levelAsync will return the latest value of the observed and promise object of the subscription. When the observer finds that the value has changed, it will trigger the checking policy of the component, and when the component is destroyed, it will automatically unsubscribe to avoid memory leakage.

In this example, if the async filter is cancelled, it will cause loading all the time, because the component can’t monitor the change of the control loading value, so it can’t update the view.

Trigger action and hide loading

Finally, paste another sentence to trigger the action code

//Control the loading display and hide, combined with the previous action load.ShowAction()); load.HideAction());


A very simple small demo, through the ngrx control project loading animation, but to tell you the truth, the code is scattered, add up quite a lot, so the writing is very messy, sorry ~ a lot of things are not easy to present in the blog, interested students can take a look at the project down.
Project address:…