Angular роутер-розетка не работает после изменения размера окна - PullRequest
0 голосов
/ 21 февраля 2020

Доброе утро, я начал месяц go, чтобы выучить 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, он изменяет распределение компонентов в зависимости от экрана. В начале все работает нормально всегда. Если я на большом экране и меняю размер на маленький, вид изменится, и маршрутизатор все еще будет работать. Но когда я go возвращаюсь на большой экран, он перестает работать. все хорошо, но ссылки для смены роутера ничего не делают. Если я go вернусь к маленькому экрану, он снова заработает.

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. responseive.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, попробуйте изменить размер на маленький, чтобы преобразовать его в мобильное представление, а затем go назад, и вы получите обратите внимание, что меню перестает работать.

Все, что вам нужно, просто спросите.

1 Ответ

0 голосов
/ 21 февраля 2020

Кажется, что <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>

Вы не увидите двух версий текущей компонент маршрута - первый игнорируется. Так, может, компилятор использует только последний найденный файл?

...