【问题标题】:Changing router-outlet with *ngIf in app.component.html in angular2在 angular2 的 app.component.html 中使用 *ngIf 更改路由器插座
【发布时间】:2017-02-25 21:41:58
【问题描述】:

我正在使用 angular 2.0 final。我正在尝试更改主 app.component.html 中 router-outlet 的位置。模板正在更新显示,除了我第一次使用 router.navigate 时,组件不会显示在新的路由器插座中,也没有错误。第二次也是每次使用 router.navigate 后,它都能正常工作。

app.component.html 的示例模板

   <div *ngIf="authenticated() == false">
      <h1>not logged in</h1>
      <router-outlet>
      </router-outlet>
    </div>
    <div *ngIf="authenticated()">
      <h1>logged in</h1>
      <router-outlet>
      </router-outlet>
    </div>

【问题讨论】:

    标签: angular angular2-routing angular2-template


    【解决方案1】:

    我遇到了同样的问题,我的 app.component.html 中有多个 &lt;router-outlet&gt;,并希望它们在 *ngIf 中可见/可见。我已经尝试了几乎所有可以在网上找到的东西(有些工作但违反了 SPA 的原则)。

    这完全适合我,我认为这是最合乎逻辑且非常简单的解决方案。

    <div *ngIf="authenticated">
      <ng-container *ngTemplateOutlet="template"></ng-container>
    </div>
    
    <div *ngIf="!authenticated">
      <ng-container *ngTemplateOutlet="template"></ng-container>
    </div>
    
    <ng-template #template>
      <router-outlet></router-outlet>
    </ng-template>

    【讨论】:

    • 当我单击“运行代码 sn-p”按钮时,我看不到任何事情发生。这是因为您的代码有问题,还是因为您的代码实际上不是可运行的 sn-p?如果是后者,请使用代码围栏而不是制作 sn-p;如果是前者,请解决问题。
    【解决方案2】:

    You can not use multiple router outlets in the same template with ngIf condition. But you can use it in the way shown below:
    
    <div *ngIf="loading">
      <span>loading true</span>
      <ng-container *ngTemplateOutlet="template"></ng-container>
    </div>
    
    <div *ngIf="!loading">
      <span>loading false</span>
      <ng-container *ngTemplateOutlet="template"></ng-container>
    </div>
    
    
    
    <ng-template #template>
      <router-outlet> </router-outlet>
    </ng-template>

    【讨论】:

      【解决方案3】:

      这样的用户路由,它将解决命名出口的问题

      {
          path: 'login',
          children: [
            {
              path: '',
              component: LoginComponent,
              outlet: 'loutlet',
            }
          ]
        },
        {
          path: 'profile',
          component: ProfileComponent,
        }

      【讨论】:

      • 您可以通过解释如何此代码的帮助来真正改善这一点。
      【解决方案4】:

      我想说请使用命名router-outlet,它工作得很好,但对我来说问题是这样的网址根本不方便用户使用,我个人认为带有插座名称的网址没有意义,

      例如:-

      路线

      { path : "forgotPassword", component :ForgotPassword , outlet : "notlogedin" }
      

      在浏览器地址栏中输出

      http://localhost:4200/(notlogedin:forgotPassword)

      看看它在地址栏中看起来多么愚蠢。

      因此,如果您尝试使用*ngIf 有条件地禁用和启用router-outlet 来解决问题,它不起作用。一个router-outlet 将被注册,无论您做什么,下一个router-outlet 都不会响应路由更改。

      这就是解决方案

      使用ngTemplateOutletng-template,我们可以通过只保留一个router-outlet 来很好地解决这个问题,请参见下面的示例代码。

      <ul>
        <li><a routerLink="/login">login</a></li>
        <li><a routerLink="/dashboard">dashboard</a></li>
      </ul>
      
      <!--This is where my before login router stays-->
      <div class="logedIn-route" *ngIf="routerActive">
      <ng-container *ngTemplateOutlet="template"></ng-container>
      </div>
      
      <!--This is where my after login router stays-->
      <div class="logedout-route" *ngIf="!routerActive">
        <ng-container *ngTemplateOutlet="template"></ng-container>
      </div>
      
      
      <ng-template #template>
        <router-outlet>
        </router-outlet>
      </ng-template>
      

      试试小提琴

      https://jsfiddle.net/imal/e4tyqv95/36/

      【讨论】:

      • 在我不得不根据您是使用台式机还是移动设备移动插座的情况下非常有帮助。
      • 不幸的是,在尝试了这个之后,似乎只有一个路由器真正响应了路由更改。
      • 让我尝试为您提供示例
      • 结合异步身份验证保护,这可能会导致调用 ngOnDestroy 而不调用 ngOnInit 的行为,就像我在这里描述的那样:stackoverflow.com/a/58394473/7662651
      【解决方案5】:

      我必须使用ViewContainerRef,以便移动设备和桌面设备都使用同一个路由器插座:

      <!-- MOBILE -->
      <div *ngIf="isMobile">
        <div #mobileOutlet></div>
      </div>
      
      <!-- DESKTOP -->
      <div *ngIf="!isMobile">
        <div #desktopOutlet></div>
      </div>
      
      <ng-template #tpl>
        <router-outlet></router-outlet> 
      </ng-template>
      

      我对两者都使用createEmbeddedView 没有问题:

      @ViewChild('mobileOutlet', { read: ViewContainerRef }) _vcrMobile;
      @ViewChild('desktopOutlet', { read: ViewContainerRef }) _vcrDesktop;
      @ViewChild('tpl') tpl;
      
      ngAfterViewInit() {
        if (this.isMobile) this._vcrDesktop.createEmbeddedView(this.tpl);
        else this._vcrMobile.createEmbeddedView(this.tpl);
      }
      

      唯一的问题是,如果您在断点之间切换,则必须切换此插座。例如,从桌面到移动调整大小:

      this._vcrDesktop.clear();
      this._vcrMobile.createEmbeddedView(this.tpl)
      

      【讨论】:

        【解决方案6】:

        您应该考虑改用命名router-outlet

        它在文档中声明:一个模板可能恰好包含一个未命名的 .

        <div *ngIf="authenticated() == false">
              <h1>not logged in</h1>
              <router-outlet name="notloggedin">
              </router-outlet>
            </div>
            <div *ngIf="authenticated()">
              <h1>logged in</h1>
              <router-outlet name="loggedin">
              </router-outlet>
            </div>
        

        路由器将如下所示:

        { path: 'page1', component: Page1Component, outlet: 'notloggedin' },
        { path: 'page2', component: Page2Component, outlet: 'loggedin' }
        

        这里是an example,来自@yurzui,this post

        【讨论】:

          猜你喜欢
          • 2017-04-29
          • 1970-01-01
          • 2017-09-30
          • 1970-01-01
          • 1970-01-01
          • 2020-01-13
          • 2017-03-21
          • 2016-09-05
          • 2017-06-02
          相关资源
          最近更新 更多