Angular 2-父路由器出口中的子组件

问题描述:

我目前正在尝试实现具有多个导航级别的angular 2应用程序. 问题是,当我的子组件未从我的路由中的父组件中明确声明时,找不到子路由器出口.

I am currently trying to implement an angular 2 application with multiple navigation levels. The problem is that my child components cannot find a router outlet when it is not explicitly declared in the parent component from my routes.

这是我收到的错误消息:

This is the error message i get:

Unhandled Promise rejection: Cannot find primary outlet to load 'EditUserComponent'

当我单击按钮或链接时,我想要类似编辑视图或详细视图的视图,而不是列表视图的视图. 视图嵌入在具有导航结构并为内容提供路由器出口的模板布局中.我也想以我的所有意见将此路由器插座定为目标.我已经尝试使用命名网点,但是没有成功. 我使用面包屑组件显示当前路线,因此无法使编辑/详细信息"视图成为列表组件的同级组件.

I want something like an edit or detail view which shows instead of the list view when i click on a button or link. The views are embedded in a template layout which has navigation structure and provides a router outlet for the content. I also want to target this router-outlet with all my views. I already tried using named outlets but without success. I use a breadcrumb component to show the current route, so i cannot make the edit/detail view to be a sibling of my list component.

为了更清楚一点,我制作了一个简短的演示:

To make it more clear, i made a plunker demo:

https://embed.plnkr.co/XXxADnS7q8FCfF4W84tS/

我该如何解决插座问题,并通过子组件定位布局的路由器插座?

How can i solve the outlet issue and target the layout's router-outlet from child components?

一种解决方案可能是将所有内容包装在UsersComponent模板中,而不是包装router outletdiv中.然后,如果组件有子级(在这种情况下为UsersEditComponent),则相应地隐藏/显示div.

One solution could be to simply wrap everything in your UsersComponent template, apart from the router outlet in a div. Then hide/show that div accordingly if the component has children (UsersEditComponentin this case) or not.

这是让您的路由器在UsersComponentUsersEditComponent之间保持正确的父/子层次结构,而在激活该路由时仍仅显示UsersEditComponent内容.

What this does is allowing your router to keep the correct parent/child hierarchy between UsersComponent and UsersEditComponent, while still ONLY showing the UsersEditComponent content when that route is activated.

这是UsersComponent的实现,完全实现了该功能:

This is an implementation of UsersComponent that does exactly that:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';

@Component({
  template: 
  `<div *ngIf="!hasChildren">
    User 1 <button md-icon-button (click)="editUser(1)">edit</button><br/>
    User 2 <button md-icon-button (click)="editUser(2)">edit</button>
  </div>
  <router-outlet></router-outlet>
  `
})

export class UsersComponent implements OnInit {
  private hasChildren: bool;
  constructor(private router: Router, private route:ActivatedRoute) { }

  editUser(id) {
    this.router.navigate(['users/edit', id]);
  }

  ngOnInit() {
    this.hasChildren = false;
    this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => {
      this.hasChildren = this.route.children.length > 0;
    }
  }
}