问题描述:

I'm looking for similar solution to ui-router abstract state in Angular2 Router.

To have "virtual" parent state to resolve some common things for child states.

网友答案:

A route doesn't need to be associated with a component. It can just have children with an empty path. You can use this "empty" route for things like guards or resolves.

One thing I didn't know until testing right now, is that Resolves (it's data) will trickle down to child routes. So if you want to "resolve some common things for child states", this might be the place to do it.

{
  path: '',
  resolve: {
    data: DummyResolve
  },
  children: [
    { path: 'one', component: Child1Component },
    { path: 'two', component: Child2Component }
  ]
}

Here is the complete test I used to test with

import { Component, Injectable, OnInit } from '@angular/core';
import { Router, Resolve, ActivatedRoute } from '@angular/router';
import { By } from '@angular/platform-browser';
import { Location, CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, inject, fakeAsync, tick, ComponentFixture } from '@angular/core/testing';

@Injectable()
class DummyResolve implements Resolve<string> {
  resolve() {
    return 'Hello Routing';
  }
}

@Component({
  template: `
    <router-outlet></router-outlet>
  `
})
class RoutingComponent {
}

@Component({
  template: `
    <h1>Child One</h1>
    <span>{{ data }}</span>
  `
})
class Child1Component implements OnInit {
  data: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.data.forEach((data: { data: string }) => {
      this.data = data.data;
      console.log(`data from child 1: ${this.data}`);
    });
  }
}

@Component({
  template: `
    <h1>Child Two</h1>
    <span>{{ data }}</span>
  `
})
class Child2Component implements OnInit {
  data: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.data.forEach((data: { data: string }) => {
      this.data = data.data;
      console.log(`data from child 2: ${this.data}`);
    });
  }
}

describe('component: RoutingComponent', function () {
  let fixture: ComponentFixture<RoutingComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        CommonModule,
        RouterTestingModule.withRoutes([
          {
            path: '',
            resolve: {
              data: DummyResolve
            },
            children: [
              { path: 'one', component: Child1Component },
              { path: 'two', component: Child2Component }
            ]
          }
        ])
      ],
      providers: [ DummyResolve ],
      declarations: [ RoutingComponent, Child1Component, Child2Component ]
    });

    fixture = TestBed.createComponent(RoutingComponent);
    fixture.detectChanges();
  });

  it('should go to child one',
    fakeAsync(inject([Router, Location], (router: Router, location: Location) => {

    router.navigate(['/one']);
    tick();
    fixture.detectChanges();
    let debugEl = fixture.debugElement;
    expect(debugEl.query(By.css('h1')).nativeElement.innerHTML).toEqual('Child One');
    expect(debugEl.query(By.css('span')).nativeElement.innerHTML).toEqual('Hello Routing');
  })));

  it('should go to child two',
    fakeAsync(inject([Router, Location], (router: Router, location: Location) => {

    router.navigate(['/two']);
    tick();
    fixture.detectChanges();
    let debugEl = fixture.debugElement;
    expect(debugEl.query(By.css('h1')).nativeElement.innerHTML).toEqual('Child Two');
    expect(debugEl.query(By.css('span')).nativeElement.innerHTML).toEqual('Hello Routing');
  })));
});
网友答案:

You can add child route like this [app.routeing.ts]

const APP_ROUTES:Routes = [
  {path: '', redirectTo: '/dashboard', pathMatch: 'full'},
  {path: 'report', component: ReportComponent, children: REPORT_ROUTES},
  ];

and child route would be

export const REPORT_ROUTES: RouterConfig = [
  { path: '', component: ReportHomeComponent },
  { path: 'server-report', component: ServerReportComponent } //  report/server-report
  { path: 'client-report', component: ClientReportComponent }  //  report/client-report
];
相关阅读:
Top