Angular 7 предупреждение директивы routerLink "Навигация сработала за пределами угловой зоны"

Я борюсь с Angular Framework, чтобы мое приложение работало гладко, но я не могу решить проблему с маршрутизацией. У меня высший уровень AppComponent а также app-routing.module.ts которые управляют навигацией через мой кастом SlideMenuComponent, Мой упрощенный HTML шаблон AppComponent:

<app-slide-menu [buttons]="menuButtons"></app-slide-menu>
<router-outlet></router-outlet>

мой SlideMenuComponent имеет следующий HTML в качестве ядра:

<nav><div *ngFor="let button of buttons">
    <a routerLink="{{button.routerLink}}"
    >{{button.name}}</a>
</div></nav>

Пользователь может перейти к '/courses' через это слайд-меню, которое контролируется CoursesComponent который разбивает ссылки на определенные CourseComponentы, которые получены с сервера. Эти компоненты находятся в своем собственном courses.module.ts модуль с собственным courses-routing.module.ts, Но когда я нажимаю любую из этих ссылок, я получаю Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'? предупреждение консоли, ngOnInit() не призывать к открытому CourseCompontentи не обновляется, пока я не нажму ни одну из кнопок на странице. У меня была эта проблема при ручной навигации через router.navigate() которая была решена путем пересылки этой задачи NgZone.runTask(router.navigate()), но почему это происходит с anchor теги и routerLink direcrives? Вот мой CoursesComponent фрагмент кода:

<nav><ul>
        <li *ngFor="let course of api.data | paginate: {
            currentPage: currentPage, itemsPerPage: limit, totalItems: api.total
        }">
           <a
               [routerLink]="course._id"
               [queryParams]="{ page: '1', limit: '5' }"
           >
            {{course.name}} ({{course.description}})
           </a>
        </li>
</ul></nav>

GIF, чтобы продемонстрировать проблему:

5 ответов

Он видит ошибку, попробуйте это в качестве обходного пути

constructor(private ngZone: NgZone, private router: Router) {}

public navigate(commands: any[]): void {
    this.ngZone.run(() => this.router.navigate(commands)).then();
}

Мы столкнулись с этой ошибкой, когда находились где-то в нашем решении.

В нашем компоненте боковой панели мы используем обнаружение изменений по нажатию, и у нас был один this.ref.detectChanges() когда произошла маршрутизация (изменение параметров), что каким-то образом нарушило маршрутизацию (возможно, выбив параллельные работающие резольверы из ngZone или что-то подобное). После изменения этого в любом случае предпочтительным this.ref.markForCheck() эта ошибка не появилась снова. Я рад, что нам не нужен обходной путь, хотя странное поведение..

Надеюсь, что это помогает любому, имеющему ту же проблему.

Поскольку нет принятого ответа, и поскольку я обнаружил, что, используя Angular 8, ответ с самым высоким рейтингом не совсем работает и требует немного дополнительных объяснений, мне нужно добавить следующее:

Моя конкретная проблема была связана с ag-grid, но я подозреваю, что любое место, куда вводится компонент, внутри *ngFor или иным образом, потенциально может вызвать эту проблему. Это очень похоже на предыдущий ответ, но вместо этого объявляет строковый параметр в функции навигации, а затем вызывает navigateByUrl вместо навигации.

import { Component, NgZone } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  template: `<tag (click)="navigate(path)">clickable text</tag>`
})

constructor(private ngZone: NgZone, private router: Router) { }

public navigate(path: string): void {
  this.ngZone.run(() => this.router.navigateByUrl(path)).then();
}

Ваш опыт может отличаться, но у меня это прекрасно сработало.

Для меня эта ошибка возникла из-за того, что часть кода работала вне NgZone. После чего у нас былthis.ref.detectChanges()работает для обнаружения изменений. Обнаруженные изменения изменят DOM и поместят<a [routerLink]="..."></a>. Это используется для нарушения маршрутизации. Решение: мы запустили часть кода за пределами NgZone внутри NgZone, но с использованиемthis.ngZone.run. Таким образом, нам не пришлось использоватьref.detectChanged()поскольку измененные (подписка на RxJS Subject) были в NgZone. Это решило проблему маршрутизации.

Надеюсь, это поможет любому, у кого такая же проблема.

Рабочий пример - обратитесь к этому

       public backButtonSubscription;
      ngAfterViewInit(): void {
        let self = this;
        this.backButtonSubscription = this.platform.backButton.subscribe(() => {
          console.log("back preseed \n \n");
    
          self._ngZone.runOutsideAngular(() => {
            setTimeout(() => {
              self.Router.navigateByUrl("/stock-management");
            }, 100);
          });
        });
      }
Другие вопросы по тегам