ngrx store - правильно обновить массив.

Я использую ngrx / store в своем приложении, и мне не удается сохранить массив. Мой массив становится пустым при запуске с помощью:

export interface AppState{
    customObjects: Array<CustomObject>;
};

export const initialState: AppState = {
    customObjects: []
};

и я пытаюсь вручную передать ему массив из двух CustomObject, используя следующую функцию:

loadCustomObjects() {
    let initialItems: CustomObject[] = [
        {
            directoryName: "d_name_1",
            brokenLinks: 0,
        },
        {
            directoryName: "d_name_2",
            brokenLinks: 0,
        }
    ];

    this.appStore.dispatch({ type: LOAD_CUSTOM_OBJECTS, payload: initialItems });
}

Вызов этой функции отправляет вызов моей функции редуктора:

export const mainReducer: ActionReducer = (состояние: AppState, действие: Действие) => {

if (typeof state == 'undefined') {
    state = initialState;
}

switch (action.type) {
    case LOAD_CUSTOM_OBJECTS:
        return Object.assign({}, action.payload)
    default: {
        return state;
    }
}

}

Кажется, все в порядке, но в массиве моего основного компонента приложения эти два объекта отсутствуют. Если я вручную установил состояние по умолчанию для этих двух CustomObject, тогда он заработает (я не могу этого сделать, так как мне нужно иметь возможность обновлять массив, когда я хочу). My HomeComponent использует:

customObjects$ Observable<Array<CustomObject>>;

constructor(private appStore: Store<AppState>) {
            appstore.select('mainReducer')
            .subscribe((data: AppState) => {

                if (typeof data != 'undefined') {
                    this.customObjects$ = Observable.of(data.customObjects);
                }
            });
}

Я проанализировал свои объекты и ожидаю увидеть, что this.customObjects $ в конечном итоге окажется массивом из двух CustomObject. Вместо этого это ScalarOservable:

ScalarObservable {_isScalar: true, value: undefined, scheduler: null} и т. Д. И т. Д.

Примечание. Я не уверен, нужно ли мне это, но я включил ChangeDetectionStrategy.onPush в раздел @Component моего домашнего компонента. Я также обязательно использовал

StoreModule.provideStore({ mainReducer })

в моем классе app.module.

Кто-нибудь знает, что я делаю неправильно и почему this.customObjects $ не является массивом из двух объектов? Я новичок в ngrx / store - я чувствую, что есть проблема с тем, как моя функция редуктора устанавливает массив, но я не уверен.


person Roka545    schedule 14.07.2017    source источник


Ответы (1)


Мне удалось заставить его работать с этим кодом:

Код, связанный с магазином:

export interface CustomObject {
  directoryName: string;
  brokenLinks: number;
}

export interface AppState {
  Main: CustomObject[];
};

export function MainReducer(state: CustomObject[] = [], action: Action) {

  switch (action.type) {
    case LOAD_CUSTOM_OBJECTS:
      return Object.assign({}, action.payload);
    default: {
      return state;
    }
  }
}

const reducers = {
  Main: MainReducer
};

Компонент / Сервис для отправки / прослушивания в магазин

customObjects: CustomObject[];

constructor(private appStore: Store<AppState>) {
  appStore.select(store => store.Main)
    .subscribe(objs => {
      this.customObjects = objs;
      console.log(this.customObjects);
    })
}


loadCustomObjects() {
  let initialItems: CustomObject[] = [
    {
      directoryName: "d_name_1",
      brokenLinks: 0,
    },
    {
      directoryName: "d_name_2",
      brokenLinks: 0,
    }
  ];

  this.appStore.dispatch({ type: LOAD_CUSTOM_OBJECTS, payload: initialItems });
}

Версия асинхронного канала:

customObjects$: Observable<CustomObject[]>;

constructor(private appStore: Store<AppState>) {
  this.customObjects$ = appStore.select(store => store.Main);
}


loadCustomObjects() {
  let initialItems: CustomObject[] = [
    {
      directoryName: "d_name_1",
      brokenLinks: 0,
    },
    {
      directoryName: "d_name_2",
      brokenLinks: 0,
    }
  ];

  this.appStore.dispatch({ type: LOAD_CUSTOM_OBJECTS, payload: initialItems });
}

<div *ngFor="let customObj of customObjects$ | async"></div>
person seescode    schedule 14.07.2017
comment
Есть ли причина, по которой массив customObjects вашего компонента НЕ является наблюдаемым? - person Roka545; 14.07.2017
comment
Это зависит от того, как вы хотите его использовать. Если вы планируете использовать асинхронный канал, вы можете использовать наблюдаемый объект напрямую, а не подписываться на него вручную. angular.io/api/common/AsyncPipe - person seescode; 14.07.2017
comment
С вашим кодом customObjects никогда не обновляется для меня, поэтому я пытаюсь использовать наблюдаемый. Всякий раз, когда я использую наблюдаемый объект, я, по крайней мере, вижу обновления, однако customObjects обновляется и становится ScalarObservable, а не массивом из двух объектов. - person Roka545; 14.07.2017
comment
Каждый раз, когда вы выполняете appStore.select (store = ›store.Main), он возвращает наблюдаемое. Просто я сразу подписываюсь на наблюдаемое. В любом случае, если вы привязываете наблюдаемое непосредственно к пользовательскому интерфейсу, вы можете использовать версию async pipe, я также обновил свой ответ с помощью этого подхода. - person seescode; 14.07.2017
comment
Это видео хорошо объясняет асинхронный канал: egghead.io/lessons/angular-2-using-the-async-pipe-in-angular-2 - person seescode; 14.07.2017
comment
Спасибо, попробую. Из любопытства, какие версии машинописного текста и node.js вы используете? Я смотрел бесчисленное количество примеров ngrx / store, и есть несколько вещей, которые просто не работают / не компилируются для меня. Например, я не могу указать необязательные параметры в своей функции редуктора - я всегда получаю синтаксическую ошибку. Мне интересно, связаны ли мои проблемы с ngrx / store с чем-то в моем проекте, о чем не упоминается в документации ngrx store. - person Roka545; 14.07.2017
comment
Я протестировал код, и у него есть эта ветка для справки: github.com/ Seecode / budget / tree / feature / stack-overflow Я использую узел 7.7.0 и машинописный текст ~ 2.2.2. Обычно я просто краду настройки package.json из примера приложения, чтобы не иметь проблем с зависимостями: github.com/ngrx/example-app - person seescode; 14.07.2017