ngrx订阅商店不会更新状态更改Angular5

时间:2018-06-14 13:46:46

标签: angular rxjs ngrx

我构建了一个应用程序,它将城市名称发送到api终点并返回该城市的天气。

它使用两个Actions,一个将更新城市,使用名称作为有效负载,Action 2加载返回的新数组以更新状态

效果使用switchMap映射api调用然后返回结果。

用于显示商店结果的select函数仅在启动页面加载(空数组)和第一组结果时检测商店更新

之后没有检测到我店内的变化

页面显示数组中的第一个对象,但状态中有3个对象。

enter image description here

app.state:

import { Cities } from '../../model/weather';

//Holds data for city weather
export interface AppState {
  readonly cityWeather: Cities[];
}

在app.module中:

import {cityWeather} from './weather/store/reducers/weather';

    export const reducers = {
        cityWeather
     };

 StoreModule.forRoot(reducers, {initialState: undefined})

减速器:

export function cityWeather(state:Cities[] = [], action:Action) : any {
    switch (action.type)  {
        case LOAD_CITIES_ACTION:
        return  handleLoadCitiesAction(state, action);
        case UPDATE_CITIES_ACTION:
        console.log(state)
        return handleUpdateCitiesAction(state, action);
    default:
        return state;
    }

}
function  handleUpdateCitiesAction(state, action):Cities[]{
    //Must always return the state
    console.log(state, action.payload)
        return state;
}

function  handleLoadCitiesAction(state, action):Cities[]{
    //Return the payload that holds the new array for cities
    console.log(action.payload)
    return action.payload;
}

@Effects

import { Injectable } from '@angular/core';
import {Actions, Effect} from "@ngrx/effects";
import 'rxjs/add/operator/switchMap';
import { WeatherService } from '../../weather.service';
import { UpdateCitiesAction, UPDATE_CITIES_ACTION, LoadCitiesAction } from '../actions/weather';
import {Observable} from "rxjs/Observable";
import {Action} from "@ngrx/store";

@Injectable()
export class WeatherEffects {

  constructor(private actions$: Actions, private weatherService: WeatherService) {

  }

  @Effect() cityWeather$: Observable<Action> = this.actions$
      .ofType<UpdateCitiesAction>(UPDATE_CITIES_ACTION)
      .switchMap(action => {
          console.log(action)
          return this.weatherService.searchWeatherForCity(action.payload)
        })
    .map(cities =>  {
        console.log(cities);
        return new LoadCitiesAction(cities)
    });
}

这就是我订阅我的商店的方式,出于测试目的,我做了两种方式:

@Component({
  selector: 'app-weather',
  template: `
  <app-search (onSearchCity)="citySearch($event)"></app-search>
  <app-results [cities]="cities$ | async "></app-results>  `
})

this.cities $ = this.store.select(state =&gt; state.cityWeather);

this.store.select(state => state.cityWeather)
.subscribe((data)=>{
  console.log(data)
})

1 个答案:

答案 0 :(得分:3)

我发布后立即解决,似乎我必须复制一份:

function  handleLoadCitiesAction(state, action):Cities[]{
    let newState = action.payload.slice(); 
    return newState;
}