【问题标题】:dataPersistence.navigation not executing when navigating to url导航到 url 时未执行 dataPersistence.navigation
【发布时间】:2020-08-27 10:35:05
【问题描述】:

在以前使用 Angular 8 和 9 的应用程序中,我使用的是基于类的操作,而不是操作创建器。这一次,我决定尝试使用动作创建器。但是,我遇到了一个问题:我之前使用this.dataPersistence.navigation(...) 用于基于导航执行的异步方法和成功操作,现在它被包裹在createEffect(() => ...) 中,但它似乎不起作用(无论它是否被包裹)

这是设置,其中大部分是样板:

package.json

"@nrwl/angular": "9.2.4",
...
"@angular/cli": "9.1.0",
"@nrwl/workspace": "9.2.4",

action.ts

export const setActivePanelId = createAction('[Interactions] Set Active Panel ID', props<{ id: string }>());

app.routes

const routes: Routes = [
  {
    path: '',
    component: MessagesContainer
  }
];

interactions.effects.ts

 onNav$ = createEffect(() =>
    this.dataPersistence.navigation(MessagesContainer, {
      run: (a: ActivatedRouteSnapshot): Observable<Action> | Action | void => {
        //An example callback, no async used yet.
        return setActivePanelId({id: a['snapshot'].queryParams.panelId});
      },
      onError: (a: ActivatedRouteSnapshot, e: any): any => {
        console.warn(e);
      }
    }));

app.module.ts

@NgModule({
  declarations: [AppComponent, MessagesContainer],
  imports: [
    BrowserModule,
    ComponentsModule,
    RouterModule.forRoot(routes, routingOptions),
    EffectsModule.forRoot([]),
    NxModule.forRoot(),
    StoreRouterConnectingModule.forRoot(),
    StoreModule.forRoot({}, { metaReducers: [] }),
    StoreDevtoolsModule.instrument({
      maxAge: 20,
      logOnly: config.environment.production
    }),
    InteractionsModule
  ],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {
}

interactions.module.ts

@NgModule({
  imports: [
    CommonModule,
    StoreModule.forFeature(
      fromInteractions.INTERACTIONS_FEATURE_KEY,
      fromInteractions.reducer
    ),
    EffectsModule.forFeature([InteractionsEffects]),
    StoreModule.forFeature(
      fromInteractions.INTERACTIONS_FEATURE_KEY,
      fromInteractions.reducer
    )
  ],
  providers: [InteractionsFacade]
})
export class InteractionsModule {}

更新: 我也试过了

@Effect() nav$ = createEffect(() =>
    this.actions$.pipe(
      // listens for the routerNavigation action from @ngrx/router-store
      navigation(MessagesContainer, {
        run: (activatedRouteSnapshot: ActivatedRouteSnapshot) => {
          return setActivePanelId({id: 'async!'});
        },

        onError: (
          activatedRouteSnapshot: ActivatedRouteSnapshot,
          error: any
        ) => {
          // we can log and error here and return null
          // we can also navigate back
          console.warn(error)
          return null;
        }
      })
    )
  );

【问题讨论】:

  • 一个对我有用的直接解决方法是添加一个监视 ngrx 导航的效果。 export const onNav = createAction('@ngrx/router-store/navigated', props&lt;{payload: any}&gt;()); 它让我可以在导航后访问路由器状态,但它确实需要效果中的逻辑来检查我在哪条路线上。需要创建的动作更少,但必须在效果中完成辨别我在哪条路线上的逻辑。
  • 我必须将 package.json 中的所有内容降级到 9.0.2 才能使 datapersistence.navigation 正常工作。

标签: angular ngrx ngrx-effects nrwl nrwl-nx


【解决方案1】:

请参考https://nx.dev/latest/angular/guides/misc-data-persistence StoreRouterConnectingModule 必须使用适当的序列化程序进行配置。 DefaultRouterStateSerializer 提供完整的路由器状态,而不是无需配置即可使用的 MinimalRouterStateSerializer。

import { NgModule } from '@angular/core';
import {
  StoreRouterConnectingModule,
  DefaultRouterStateSerializer,
} from '@ngrx/router-store';

@NgModule({
  imports: [
    StoreRouterConnectingModule.forRoot({
      serializer: DefaultRouterStateSerializer,
    }),
  ],
})
export class TodosModule {}

【讨论】:

  • 很惊讶这个答案对我完全有效。在 nx 工作区中将 ngrx 从版本 8 更新到更高版本时,我也面临与本文所述相同的问题。看来 DefaultRouterStateSerializer 正是需要显式写出来的,看来 DefaultRouterStateSerializer 这里不是默认的。
【解决方案2】:

我的第一反应是问你是否在任何地方导入了NxModule.forRoot()?我通常把它放在我的应用程序根模块中。

除此之外,如果你坚持这种模式:

onNav$ = createEffect(() =>
this.dataPersistence.navigation(MessagesContainer, {

你做得对。

这是我正在处理的另一个项目中非常相似(工作)的代码:

`selectCustomer$ = createEffect(() =>
    this.dataPersistence.navigation(CustomerDetailComponent, {
        run: (
            r: ActivatedRouteSnapshot,
            _state: CustomerDetailPartialState
        ) => {
            const customerId = grabIdFromParams(r.paramMap);

            return CustomerDetailActions.customerSelected({ customerId });
        },
        onError: (_a: ActivatedRouteSnapshot, error: any) => {
            throw new Error(error);
        }
    })
);`

很遗憾,我没有任何其他建议。我希望有所帮助或其他人有更好的东西。祝你好运!

【讨论】:

  • 无论如何,我都非常感谢您的反馈!是的,我在 app.module 中有 NxModule.forRoot()。顺便说一句,即使是旧方法(例如@effect() nav$ = this.dataPersistence.navigation)也不起作用。我只能想象还有其他不符合眼睛的事情发生。幸运的是,我有可运行的项目进行比较,所以我可以逐行比较。
  • 谢谢!我在一个较新的项目上遇到了依赖问题——但这些是我尝试构建时在控制台中抛出的实际错误。修复它涉及将 github 中的 data-persistence.ts 文件直接复制粘贴到我的项目中(它只有一个文件)。并不是说你应该这样做,但如果你需要真正单步调试一些源代码,这是一个选择。我希望你能弄清楚!
猜你喜欢
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2013-10-03
  • 2021-10-07
  • 1970-01-01
  • 2018-09-14
相关资源
最近更新 更多