Angular 7 routerLink指令警告“在Angular区域之外触发了导航”

时间:2018-11-03 17:00:09

标签: angular angular-routing angular-router angular7 angular-routerlink

我正在努力使用Angular框架来使我的应用程序平稳运行,但是我无法解决路由问题。 我有一个顶级AppComponentapp-routing.module.ts,它们通过我的自定义SlideMenuComponent管理导航。我的AppComponent的简化html模板:

<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抄写器会发生这种情况? 这是我的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:

  

enter image description here

5 个答案:

答案 0 :(得分:14)

它看到一个错误,请尝试解决此问题

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

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

答案 1 :(得分:3)

由于没有可接受的答案,而且自从我发现使用Angular 8以来,排名靠前的答案不太奏效,并且需要更多说明,我需要添加以下内容:

我的特定问题是关于ag-grid的,但是我怀疑在*​​ ngFor或其他范围内注入组件的任何地方都可能引起此问题。这与上一个答案非常接近,但是在Navigation函数中声明了一个字符串参数,然后调用了NavigationByUrl而不是Navigation。

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

您的里程可能会有所不同,但这对我来说效果很好。

答案 2 :(得分:0)

我们在解决方案中的某个地方导航时遇到了此错误。

在侧边栏组件中,我们使用按动变化检测,并且在发生路由(参数更改)时只有一个this.ref.detectChanges(),这以某种方式中断了路由(可能将并行运行的解析器踢出了ngZone或类似的东西) 。 将其更改为首选this.ref.markForCheck()后,此错误不再出现。 我很高兴我们不需要解决方法,但是行为很奇怪。.

希望这可以帮助遇到相同问题的任何人。

答案 3 :(得分:0)

对我来说,此错误是由于部分代码在NgZone外部运行所致。之后,我们运行this.ref.detectChanges()来检测更改。检测到的更改将更改DOM并放入<a [routerLink]="..."></a>。这用于中断路由。 解决方案:我们在NgZone中的NgZone外部运行了部分代码,但是使用了this.ngZone.run。这样,由于NgZone中已更改(RxJS Subject订阅),因此我们不必使用ref.detectChanged()。这样解决了路由问题。

希望这可以帮助遇到相同问题的任何人。

答案 4 :(得分:0)

工作示例 - 请参阅此

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