Динамическое добавление вспомогательного именованного выхода маршрутизатора

#angular #angular2-routing

#angular #angular2-маршрутизация

Вопрос:

Я хотел бы добавить <router-outlet name="param"></router-outlet> среду выполнения.

С помощью этого кода new RouterOutlet(this.parentOutletMap, this.rox, this.resolver, 'test'); добавляется router-outlet, но когда я вызываю маршрут, возникает ошибка

 "zone.js:357 Error: Uncaught (in promise): Error: Cannot find the outlet test to load 'AuxComponent'"
  

Пытаюсь динамически добавить маршрутизатор-аутлет в основной AppComponent, все работает правильно, ошибка только в лениво загруженных модулях.

Кажется, что this.router.navigateByUrl и this.router.navigate , используйте только родительскую карту розеток вместо дочерней карты.

введите описание изображения здесь

Plnkr: http://plnkr.co/edit/0W5oZuCTE4dvkNhbvs52?p=preview

GitHub: https://github.com/fabriziodebortoli/dynamic-routing /

Код:

приложение.маршрутизация

 export const appRoutes: Routes = [
    { path: '', component: HomeComponent },
    {
        path: 'page',
        loadChildren: () => new Promise(function (resolve) {
            (require as any).ensure([], function (require: any) {
                resolve(require('../pages/page.module').default);
            });
        })
    }
];
  

страница.модуль

 export const routing: ModuleWithProviders = RouterModule.forChild([
  { path: '', component: PageComponent },
  {
    path: 'wrap', component: PageComponent, children: [
      { path: 'test', component: AuxComponent, outlet: 'test' }
    ]
  },
]);

@NgModule({
  imports: [ CommonModule, FormsModule, routing],

  // added after Günter comment
  // entryComponents: [RouterOutlet], RouterOutlet is not a Component
  entryComponents: [OutletComponent],

  declarations: [PageComponent],
  exports: [PageComponent]
})
export default class PageModule {}
  

страница.компонент

 @Component({
    template: `Page 
        <hr>
        <button (click)="createRouterOutlet('test')">add</button>
        <button (click)="go()">go</button>
        <div #rox></div>`
})
export class PageComponent implements OnInit {

    @ViewChild('rox', { read: ViewContainerRef }) rox: ViewContainerRef;

    constructor(private router: Router,
        private parentOutletMap: RouterOutletMap,
        private resolver: ComponentFactoryResolver
    ) { }

    ngOnInit() {
        console.info(this.parentOutletMap);
    }

    createRouterOutlet(name: string) {
        // commented after Günter comment
        // let ro: RouterOutlet = new RouterOutlet(this.parentOutletMap, this.rox, this.resolver, name);
        // console.info(this.parentOutletMap);

        // added after Günter comment
        let factory = this.resolver.resolveComponentFactory(OutletComponent);
        let cmpRef = this.ros.createComponent(factory);
        console.info(cmpRef);
    }

    go() {
        this.router.navigateByUrl('/page/wrap/(test:test)');
    }
}
  

Редактировать: я попытался обернуть RouterOutlet пользовательским компонентом OutletComponent, но у меня есть сообщение об ошибке «Пока не удается найти тест выхода для загрузки вспомогательного компонента»

outlet.component

 import { Component } from '@angular/core';

@Component({
  selector: 'app-outlet',
  template: `<router-outlet [attr.name]="name"></router-outlet>`
})
export class OutletComponent{
  private name: string = 'test';
}
  

Ответ №1:

Вы не можете создать компонент с new помощью , это создает только экземпляр класса components, но без чего-либо, что фактически делает его компонентом Angular2.

 let factory = this.componentFactoryResolver.resolveComponentFactory(RouterOutlet);
this.cmpRef = this.rox.createComponent(factory)
/// this.comRef.instance... to access the router outlet instance
  

Комментарии:

1. Спасибо! Я пытался, но у меня ошибка No component factory found for RouterOutlet

2. Не могли бы вы попробовать добавить RouterOutlet в entryComponents свой @NgModule() ?

3. Uncaught Error: Could not compile 'RouterOutlet' because it is not a component.

4. Я не знал RouterOutlet , что это директива, а не компонент. Я уверен, что это был компонент, когда я в последний раз проверял;-) (хотя это ненадолго). Я думаю, вам нужно обернуть его пользовательским компонентом, а затем добавить этот компонент вместо этого.

5. Не похоже, что привязка к name поддерживается. Пожалуйста, попробуйте вместо <router-outlet name="test"> этого router outlet использует внедрение конструктора для name атрибута, и он считывается только при создании компонента, но не при его последующем добавлении или обновлении (что связано с привязкой). Вы можете создать свою собственную реализацию, которая использует @Input() name:String и отменяет регистрацию с предыдущего имени и регистрируется с новым именем. github.com/angular/angular/blob /…