Angular 路由器插座在 window 调整大小后不工作

Angular router-outlet does not work after resize of window

早上好,我一个月前开始学习Angular,我正在做自己的作品集,到目前为止一切顺利。

路由器插座有问题。一开始它运行良好,但在进行了一些更改以使网络响应后,现在它会做一些奇怪的事情。

1. app.component.html

<!-- If large screen -->
<div (window:resize)="onResize()" class="row mainpage h-100" *ngIf="!isMobile">
  <div class="col-lg-9 maincontent">
      <cabecera></cabecera>
      <section id="main" class="wrapper">
          <router-outlet></router-outlet>
      </section>
  </div>
  <div id="menu" class="col-lg-3 mainmenu menuwrapper">
    <mainmenu></mainmenu>
  </div>
</div>

<!-- If small screen -->
<div (window:resize)="onResize()" class="row mainpage h-100" *ngIf="isMobile">
  <div class="col-xs-12 maincontent">
    <div id="menu" class="mainmenu">
      <mainmenumovil></mainmenumovil>
    </div>
    <section id="main" class="maincontentmobile">
        <router-outlet></router-outlet>
    </section>
  </div>
</div>

正如您在 1 中看到的,它会根据屏幕更改组件的分布。一开始它总是工作正常。如果我在大屏幕并调整到小屏幕,视图会改变,路由器仍然有效。但是当我回到大屏幕时,它就停止工作了。一切都很好,但更改路由器插座的链接没有任何作用。如果我回到小屏幕,它就会再次工作。

2。 app.component.ts

import { Component, OnInit } from '@angular/core';
import {ResponsiveService} from './utils/responsive.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'SilesBonilla';
  public isMobile: Boolean;
  constructor(private responsiveService:ResponsiveService){
  }
  ngOnInit(){
    this.responsiveService.getMobileStatus().subscribe( isMobile =>{
      if(isMobile){
        console.log('Mobile device detected');
        this.isMobile = true;
      }
      else{
        console.log('Desktop detected');
        this.isMobile = false;
      }
    });
    this.onResize();
  }

  onResize(){
    this.responsiveService.checkWidth();
  }
}

3。 responsive.service.ts

import { Injectable } from '@angular/core';
import { Subject } from "rxjs/Subject";
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { Observable } from "rxjs/Observable";

@Injectable()
export class ResponsiveService {
    private isMobile = new Subject();
    public screenWidth: string;


    constructor() {
        this.checkWidth();
    }

    onMobileChange(status: boolean) {
        this.isMobile.next(status);
    }

    getMobileStatus(): Observable<any> {
        return this.isMobile.asObservable();
    }

    public checkWidth() {
        var width = window.innerWidth;
        if (width <= 992) {
            this.screenWidth = 'sm';
            this.onMobileChange(true);
        }  else {
            this.screenWidth = 'lg';
            this.onMobileChange(false);
        }
    }
}

在 2 和 3 中你可以看到我在从小屏幕切换到大屏幕时没有做任何特别的事情,实际上这是从我遵循的教程中复制粘贴的。

4。 app.routing.ts

(imports)

const appRoutes: Routes = [
    {path: '', redirectTo: 'home', pathMatch: 'full'},
    {path: 'home', component: HomeComponent},
    {path: 'experience', component: ExperienceComponent},
    {path: 'projects', component: ProjectsComponent},
    {path: 'studiesskills', component: StudiesskillsComponent},
    {path: 'certifications', component: CertificationsComponent},
    {path: 'hobbies', component: HobbiesComponent},
    {path: 'projects/projectGo',component: ProjectGoComponent},
    {path: 'projects/projectIndex',component: ProjectIndexComponent},
    {path: '**', component: ErrorComponent} // ESTA SIEMRPE DEBE SER LA ULTIMA DE TODAS.
];

export const appRoutingProviders: any[] = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

我在菜单中使用这样的代码行来调用路由器插座

<a rel="noopener" class="menuitem row menuitemelement" [routerLink]= "['/home']" [routerLinkActive]="['menuitemelementselected']"><h5 class="centrado">Home</h5></a>

再说一次,没什么特别的。 如果你不太理解奇怪的行为,你可以在我的网站上查看 https://silesbonilla.com 尝试将大小更改为小以将其转换为移动视图,然后返回,你会发现菜单停止工作.

还有什么需要的就问。

似乎 <router-outlet> 表现得像 <ng-content>。如果您在同一组件中有重复的版本(即使它们受到 *ngIf 的保护),也只会使用一个*。

我解决这个问题的方法与解决 <ng-content> 问题的方法相同 - 通过使用带有模板出口的模板。

最小化 HTML 来演示我的解决方案:

<div (window:resize)="onResize()" *ngIf="!isMobile">
  <ng-container *ngTemplateOutlet="routeroutlet">
  </ng-container>
</div>

<div (window:resize)="onResize()" *ngIf="isMobile">
  <ng-container *ngTemplateOutlet="routeroutlet">
  </ng-container>
</div>

<ng-template #routeroutlet>
  <router-outlet></router-outlet>
</ng-template>

演示:https://stackblitz.com/edit/router-template-vvwum9

*我没有这方面的官方文档。我是根据创建具有复杂 <ng-content> 处理的组件的经验说的。

您可以通过执行以下操作对此进行试验。

<div class="first">
  <router-outlet></router-outlet>
</div>
<div class="second">
  <router-outlet></router-outlet>
</div>

您不会看到当前路线组件的两个版本 - 第一个被忽略。所以也许编译器只使用它找到的最后一个?