Как я могу выполнить действие / эффект после инициализации свойств в моем состоянии?

У меня есть хранилище для компонента, который является новым с каждым новым объявлением компонента. В ngOnInit мне нужно установить значение трех свойств состояния редуктора. После того, как это будет выполнено, мне нужно вызвать другой диспетчер, который запускает эффект, загружающий данные с моего сервера.

В частности, данные, загружаемые эффектом, должны ссылаться на три предыдущих свойства состояния, которые инициализируются в состоянии. Однако, когда я устанавливаю точку останова в эффекте, данные равны нулю, что говорит мне, что мои вызовы диспетчеризации для установки значений не завершены.

Я знаю, что вы должны подписаться на данные, которые сохраняются в магазине, а затем реагировать на них. Может быть, это то, что мне нужно сделать, но я не могу понять, как последовательно связать назначение трех свойств состояния и ЗАТЕМ вызвать диспетчеризацию, которая запускает эффект загрузки данных NgRx. Вот какой-то псевдокод того, что я пытаюсь сделать.

Изнутри ngOnInit

this.store.dispatch(actions.set_foo({ value: "A"}))
this.store.dispatch(actions.set_bar({ value: "B"}))
this.store.dispatch(actions.set_baz({ value: "C"}))

//This will call an effect.  The effect needs the data stored in state.foo, state.bar and state.baz
//How do I change this call so that it waits/subscribes to the assignment of Foo, Bar & Baz?
this.store.dispatch(actions.load_data_from_server());

Изнутри вызываемого эффекта

loadData$ = createEffect(
  ()=>this.actions$.pipe(
    ofType(actions.load_data_from_server),

    //selectParameterData is a selector that returns a composite object of Foo/Bar/Baz. There might be a better way to do this, but this allowed me to get three state properties in one.
    withLatestFrom(this.store$.select(selectors.selectParameterData),
    mergeMap([action, data]=>
    
    ... Code that makes a data ball to the server, passing in values from Foo/Bar/Baz ...
        This the place where the data is uninitialized.   
  )
)

Обратите внимание, я могу реструктурировать весь этот код, но это должно быть сделано правильно. Наша команда решила, что нам нужно перенести наше приложение Angular на NgRx, и это проблемы, которые мне нужно решить, настроив пример миграции части нашего приложения на NgRx. Спасибо за любую помощь.

Итак, это явно вопрос, как мне установить несколько свойств в моем состоянии и только после того, как они будут назначены, загрузить данные с сервера, ссылаясь на эти свойства в моем объекте состояния редуктора?


person RLH    schedule 05.11.2020    source источник


Ответы (1)


Вы можете связать обработчики действий следующим образом:

Изнутри ngOnInit

this.store.dispatch(actions.set_all({ a: "A", b: "B", c: "C"} ));

Изнутри вызываемого эффекта

setAll$ = createEffect(
  () =>  this.actions$.pipe(
      ofType(actions.set_all),
      concatMap(t => {
         return [
            actions.set_foo({ value: t.a} ),
            actions.set_bar({ value: t.b} ),
            actions.set_baz({ value: t.c} ),
            actions.load_data_from_server
         ];
      })
)
loadData$ = createEffect(
  ()=>this.actions$.pipe(
    ofType(actions.load_data_from_server),

    //selectParameterData is a selector that returns a composite object of Foo/Bar/Baz. There might be a better way to do this, but this allowed me to get three state properties in one.
    withLatestFrom(this.store$.select(selectors.selectParameterData),
    mergeMap([action, data]=>
    
    ... Code that makes a data ball to the server, passing in values from Foo/Bar/Baz ...
        data is now initialized.   
  )
)

Альтернативное решение

Или запланируйте отправку с помощью асинхронного планировщика с setTimeout, который запустит последнюю отправку в следующем цикле цикла событий. Предупреждение: это вызовет обнаружение изменений во второй раз (по сравнению с предыдущим решением).

this.store.dispatch(actions.set_foo({ value: "A"} ))
this.store.dispatch(actions.set_bar({ value: "B"}))
this.store.dispatch(actions.set_baz( { value: "C" }))
setTimeout(() => {
    this.store.dispatch(actions.load_data_from_server());
});
person pixelbits    schedule 05.11.2020