【问题标题】:Route Data Subscription in Angular is not triggerd from resolverAngular中的路由数据订阅不是从解析器触发的
【发布时间】:2019-05-06 02:40:10
【问题描述】:

我有一个组件,它在顶部显示详细信息,并在API 调用后填充了一个选择选项。我已经使用 select 选项来确定下一条路线。

我已经使用 router-outlet 根据所选选项加载组件。所有要加载的组件都是惰性加载的。

Template

<div>
    Detail Section
</div>

<div> Select Option Section </div>
<div>
    <router-outlet></router-outlet>
</div>

我的路由数组如下:-

const routes: Routes = [
  {
    path: ':id',
    component: ParentComponent,
    canActivate: [AppRouteGuard],
    children: [
        {
            path: 'path1',
            loadChildren:'path-to-module',
            canActivate: [AppRouteGuard]
       },
       ...
    ]
  }
];

假设我有一个变量,即routeSelector,它确定要命中的路线。所有子路由都是延迟加载的模块。我需要routeSelector 变量来确定API 端点在Resolver 中的每个Child Modules 中被击中。

所以当我第一次导航到父路由,即/:id 根据上述路由数组时,我将变量存储在服务中,以便我可以在需要时订阅该值。

如果我导航到选择任何选项的子路线,一切正常。但是如果我在子路由中,即/:id/path1,我无法在第一次点击时在解析器中获得routeSelector 变量的值。随后,routeSelector 值被检索,导致 API 调用,但结果未反映在组件中。

Service Code

@Injectable()
export class ServiceName() {
   private subject$ = new BehaviorSubject('');
   constructor() { }  

   getRouteSelector() {
       return this.subject$ as Observable;
   }

   setRouteSelector(str: string) {
    this.subject$.next(str);
  }

}

Resolver Code

resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<model1 | model2> {
    const id= route.params.id;
    let observable$: Observable<model1| model2>;

    this._routeSelectorService.getRouteSelector()
      .subscribe((routeSelector) => {
        if (routeSelector) {
          switch (routeSelector) {
            case 'Model 1':
              observable$ = this._model1Service.getModel1(id);
              break;
            case 'Model 2':
              observable$ = this._model2Service.getModel2(id);
              break;
          }
        }
      });
    return observable$;
  }
}

Component Code

ngOnInit() {
    this.routeDataSubscription = this.route.data.subscribe(
      ({ model}) => {
        this.model= model;
        // Checks if model is received or not and set a value to a bool
        // say `isDataReceived`
      }
    );
  }
}

Component Template Code

<div *ngIf="isDataReceived; else noData">
    Display the Model Value
</div>

<ng-template #noData>
   No Data Received
</ng-template>

因此在刷新页面时,我总是最终得到模板的else 部分。

我该如何解决这个问题?任何帮助表示赞赏。

【问题讨论】:

    标签: angular


    【解决方案1】:

    问题在于,observable$ 由于其异步特性,实际上总是会在 subscribe() 执行之前返回。如果目标是从 getModel1()getModel2() 返回 observable,则可以使用 RxJS 管道运算符,例如 switchMap(),而不是使用 subscribe()

    import { Observable, of } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    // ...
    
    resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<model1 | model2> {
        const id = route.params.id;
    
        return this._routeSelectorService.getRouteSelector()
          .pipe(switchMap(routeSelector) => {
            if (routeSelector) {
              switch (routeSelector) {
                case 'Model 1':
                  return this._model1Service.getModel1(id);
                case 'Model 2':
                  return this._model2Service.getModel2(id);
                default:
                  return of(null); // need to handle when not 'Model 1' or 'Model 2'
              }
            } else {
              return of(null); // need to handle falsy `routeSelector` value
            }
          });
      }
    }
    

    希望对您有所帮助!

    【讨论】:

    • 它不起作用...现在到/:id/path 的路由没有被路由
    • 能否分享一下getRouteSelector()的代码?
    • 我更新了显示服务中的 getRouteSelector() 方法的问题
    猜你喜欢
    • 2018-07-07
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 2020-12-07
    • 2015-06-01
    • 2016-03-21
    • 2017-06-25
    • 1970-01-01
    相关资源
    最近更新 更多