在修改组件层次结构时遇到路由器错误

时间:2017-06-27 19:26:38

标签: angular angular-routing angular-router

用例有点复杂,我不得不转向Plunker's help to demonstrate the issue

整个想法是以实时方式根据窗口大小更改页面设计。在给定的链接中,如果窗口小于600px,则父模板显示2列表,当它超过600px时,它会在3列表中显示内容(仅作为示例)。

复制问题的步骤(您也可以在Plunker页面中找到它们):

  1. 打开您的开发者工具
  2. 点击"打开中间孩子"
  3. 点击"打开孙子"
  4. 点击"打开中间孩子"
  5. 调整预览窗口的大小,如果小于600px,请将其放大。否则,使其小于600px(只需更改状态)
  6. 点击"打开孙子"
  7. 错误是:

    • 在第5步之后,"孙子"不应该被显示
    • 执行步骤6将导致您在控制台
    • 中看到错误

    我认为问题依赖于有多个<router-outlet>这一事实,并且Angular不支持它们之间的切换。我希望有办法解决这个问题!

    以下app.ts的代码符合SO:

    //our root app component
    import { Component, NgModule, VERSION, OnInit, HostListener } from '@angular/core'
    import { BrowserModule } from '@angular/platform-browser'
    import { RouterModule, Router } from '@angular/router';
    
    @Component({
      selector: 'my-app',
      template: `
        <div (window:resize)="onResize($event)" style="width: 100%; height: 100%">
          Steps to replicate the problem:
          <ol>
            <li>Open your developer tools</li>
            <li>Click on "Open middle child"</li>
            <li>Click on "Open grand child"</li>
            <li>Click on "Open middle child"</li>
            <li>Resize the preview window in a way that if it was less than 600px, make it larger. Otherwise, make it smaller than 600px (just change the state)</li>
            <li>Click on "Open grand child"</li>
          </ol>
          Notes:
          <ul>
            <li>After step 5, the "Grand child" should have not been shown</li>
            <li>Following step 6 will result in an error that you can see in console</li>
          </ul>
          <table *ngIf="columns == 2" class="frame">
            <tr>
              <td colspan="2">2-Column design - "{{router.routerState.snapshot.url}}"</td>
            </tr>
            <tr>
              <td><a [routerLink]="['/middle-child']">Open middle child</a></td>
              <td><router-outlet></router-outlet></td>
            </tr>
          </table>
    
          <table *ngIf="columns == 3" class="frame">
            <tr>
              <td colspan="3">3-Column design - "{{router.routerState.snapshot.url}}"</td>
            </tr>
            <tr>
              <td><a [routerLink]="['/middle-child']">Open middle child</a></td>
              <td><router-outlet></router-outlet></td>
              <td>3rd column</td>
            </tr>
          </table>
        </div>
      `,
    })
    export class App implements OnInit {
      name:string;
      columns: number = 2;
      constructor(private router: Router) {
        this.name = `Angular! v${VERSION.full}`
      }
      ngOnInit() {
        this.columns = window.innerWidth < 600 ? 2 : 3;
      }
      @HostListener('window:resize', ['$event'])
      onResize(event) {
        this.columns = event.target.innerWidth < 600 ? 2 : 3;
      }
    }
    
    @Component({
      template: `
      <table>
        <tr><td>Middle child here</td></tr>
        <tr><td><a [routerLink]="['/middle-child/grand-child']">Open grand child</a></td></tr>
        <tr><td><router-outlet></router-outlet></td></tr>
      </table>
      `
    })
    export class MiddleChild {}
    
    @Component({
      template: `Grand child`
    })
    export class GrandChild {}
    
    @NgModule({
      imports: [
        BrowserModule,
        RouterModule.forRoot([
          { path: 'middle-child', component: MiddleChild, children: [
            { path: 'grand-child', component: GrandChild }
          ] }
        ])
      ],
      declarations: [ App, MiddleChild, GrandChild ],
      bootstrap: [ App ]
    })
    export class AppModule {}
    

1 个答案:

答案 0 :(得分:0)

您有两个不同的表,按列数切换,这会使Angular Router感到困惑。我相信。

我用下面的代码改进了你的代码。

<td [colSpan]="columns">{{columns}}
...
<td *ngIf="columns == 3">

检查我的修改版本:https://plnkr.co/edit/hGDJgT8rF7hl2FOZw3Eh?p=preview