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>
您不会看到当前路线组件的两个版本 - 第一个被忽略。所以也许编译器只使用它找到的最后一个?
早上好,我一个月前开始学习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>
您不会看到当前路线组件的两个版本 - 第一个被忽略。所以也许编译器只使用它找到的最后一个?