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);
});
});
}