简体   繁体   中英

Angular2 Router and Multiple Resolves in one route

In ui-router it's easy to make multiple resolves defined in the route configuration, so let's say something like:

export const APP_STATES: Ng2StateDeclaration[] = [
  {
    name: 'dashboard',
    url: '/dashboard', 
    component: DashboardComponent,
    resolve: [
      {
        token: 'playbookDurations',
        deps: [DashboardService],
        resolveFn: (svc: DashboardService) => svc.getPlaybookDurations()
      },
      {
        token: 'playbookSuccesses',
        deps: [DashboardService],
        resolveFn: (svc: DashboardService) => svc.getPlaybookSuccesses()
      },
      {
        token: 'playbookRuns',
        deps: [DashboardService],
        resolveFn: (svc: DashboardService) => svc.getPlaybookRuns()
      },
      {
        token: 'activityLog',
        deps: [DashboardService],
        resolveFn: (svc: DashboardService) => svc.getActivityLog()
      }
    ]
  }
}];

when using the Angular2 router is requires you to implement a resolver pattern for the resolve parameter. So something like this:

import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
import { DashboardService } from '.';

@Injectable()
export class DashboardResolver implements Resolve<any> {

  constructor(private dashboardService: DashboardService) { }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.dashboardService.get();
  }

}

then in my route I do something like:

import { DashboardComponent } from './dashboard.component';
import { DashboardResolver } from './dashboard.resolver';

export const routes = [
  { 
    path: '', 
    children: [
      {
        path: '', 
        component: DashboardComponent,
        resolve: {
          data: DashboardResolver
        }
      }
    ]
  }
];

problem is there is only ONE resolve. How does one implement multiple resolve arguments as the ui-router implementation does?

I suppose you have 2 options: implement resolvers for each one of those inputs OR have the resolve return an object with all your resolves nested. The first seems pretty ceremonial and the second sounds pretty hacky so there has to be a better way.

Alright, I hope I haven't misunderstood the question.

Angular's router supports as many resolvers per route as you want.

In the route declaration, the resolve property is an object and it can have as many keys as you'd like:

{
  path: '', 
  component: DashboardComponent,
  resolve: {
    foo: Resolver1
    bar: Resolver2,
    // more resolves here...
  }
}

Then retrieve the resolved data from your component:

@Component({ ... })
export class MyComponent {

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    const foo = this.route.snapshot.data['foo'];
    const bar = this.route.snapshot.data['bar'];
  }

}

The route won't be activated until ALL resolves are complete/fulfilled.

You can achieve the same results while using ONLY ONE RESOLVER:

resolve(route: ActivatedRouteSnapshot,state: RouterStateSnapshot,): Observable<any> {
    let companyIdentifierTypes = this.companiesService.getCompanyIdentifierTypes();
    let mobilePrefixes = this.registrationService.getMobilePrefixes();
    let data = {companyIdentifierTypes: companyIdentifierTypes, mobilePrefixes: mobilePrefixes};
    return Observable.of(data);
}

and fetch the resolved data this way:

fetchDataBeforeViewRender() {
    let data =  this.route.snapshot.data['data'];
    if(data != null) {
        data.companyIdentifierTypes.subscribe(data => {this.identityTypeIDList = data;});
        data.mobilePrefixes.subscribe(data => {this.mobilePrefixOptions = data;});
    }
}

make sure to name the resolver correctly!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM