Angular NgRx-序列化辅助插座,如何

时间:2019-11-15 16:16:03

标签: angular angular-ui-router ngrx

说我有以下网址:
http://localhost:4200/cats(sidePanel:muffins)

我现在可以使用自定义路由序列化器来获取网址:

export class CustomRouteSerialiser implements RouterStateSerializer<NotImportantForStackOverflow> {
  serialize(routerState: RouterStateSnapshot) {
    let route = routerState.root;

    while (route.firstChild) {
        route = route.firstChild;
    }

    const { url } = routerState;

    return {
        url,
    };
  }
}

但是我没有关于辅助路线“ sidePanel”的信息。
我唯一可以找到的地方是:

routerState.root._urlSegment.children.sidePanel.segments  

但是,这是我不应该使用的非类型化私有财产,但与此同时我找不到其他任何东西。
关于如何以一种干净的方式执行此操作,我找不到任何内容。

那么,我应该如何以干净的方式序列化辅助插座?

P.S .:而不是经过routerState.root._urlSegment.children.sidePanel.segments然后在那一点映射细分数组,我宁愿复制信息并在其他地方手动存储辅助路由,脏的还是脏的……

我当前的解决方案(对此我不满意):

// tslint:disable-next-line:no-any
const sidePanelOutlet  = (routerState.root as any)._urlSegment.children.sidePanel;
const auxiliaryOutlets = {
    sidePanel: sidePanelOutlet && sidePanelOutlet.segments[ 0 ].path,
};

1 个答案:

答案 0 :(得分:0)

那么,让我们了解一些背景信息。在我的例子中,我有可能在主要出口中有多个参数,以及有一个带有参数的辅助路由的可能性。 示例路线:/user/lgxAXtn...h2/home(modal:items/0fn...Z83)
所以,我想出的解决方案是创建所有参数的集合。首先,我们需要打破递归以减少混乱(至少对我而言)

traverse(root: ActivatedRouteSnapshot): Params {
  // The object to be returned
  let params: Params = {};
  // The starting point
  let route = root;
  // Iterate til we hit the end
  while (route.firstChild) {
    route = route.firstChild;
    // Collect all params on the way there (if any)
    params = { ...params, ...route.params };
  }
  return params;
}

现在,这完成了大部分繁重的工作,但我们还没有完全完成。

serialize(routerState: RouterStateSnapshot): RouterReducer.State {
  // Since we want an object, we can just reduce the array.
  // root.children provides primary and modal outlets
  const params = routerState.root.children.reduce(
    (acc, curr) => ({ ...acc, ...this.traverse(curr) }),
    {}
  );
  // Full url
  const { url } = routerState;

  return { url, params };
}

结果?

state: {
  url: '/user/lgxAXtn...h2/home(modal:items/0fn...Z83)',
  params: {
    userId: 'lgxAXtn...h2',
    itemId: '0fn...Z83'
  }
}

这是我想出的更有趣的小解决方案之一,到目前为止它一直对我很好。如果您在使用此方法时遇到任何问题,请告诉我!

完整的serializer.ts

import {
  ActivatedRouteSnapshot,
  Params,
  RouterStateSnapshot
} from '@angular/router';
import { RouterStateSerializer } from '@ngrx/router-store';
import * as RouterReducer from '../reducers/router.reducer';

export class ParamSerializer
  implements RouterStateSerializer<RouterReducer.State> {
  private traverse(root: ActivatedRouteSnapshot): Params {
    // The object to be returned
    let params: Params = {};
    // The starting point
    let route = root;
    // Iterate til we hit the end
    while (route.firstChild) {
      route = route.firstChild;
      // Collect all params on the way there (if any)
      params = { ...params, ...route.params };
    }
    return params;
  }

  serialize(routerState: RouterStateSnapshot): RouterReducer.State {
    // Since we want an object, we can just reduce the array.
    // root.children provides primary and modal outlets
    const params = routerState.root.children.reduce(
      (acc, curr) => ({ ...acc, ...this.traverse(curr) }),
      {}
    );
    // Full url
    const { url } = routerState;
    return { url, params };
  }
}

现在,在我的实例中,我将它用于参数 - 获取段只是一点点修改。类似于 route.url 而不是 traverse 函数中的 route.params。