24

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

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

MySlideMenuComponent有以下 html 作为其核心:

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

用户可以'/courses'通过此滑动菜单导航到,该菜单由对从服务器检索CoursesComponent到的特定 s 的链接进行分页管理。CourseComponent这些组件驻留在自己的courses.module.ts模块中,并拥有自己的courses-routing.module.ts. 但是,当我单击任何这些链接时,我会收到Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?控制台警告,ngOnInit()不要求 openned CourseCompontent,并且在我单击页面上的任何按钮之前它不会更新。我在手动导航时遇到了这个问题,router.navigate()通过将此任务转发到解决了这个问题NgZone.runTask(router.navigate()),但是为什么anchor标签和routerLinkdirecrives 会发生这种情况?这是我的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 来演示这个问题:

在此处输入图像描述

4

5 回答 5

39

它看到了一个错误,试试这个作为一种解决方法

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

public navigate(commands: any[]): void {
    this.ngZone.run(() => this.router.navigate(commands)).then();
}
于 2018-11-08T18:21:17.623 回答
5

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

在我们的侧边栏组件中,我们使用 on-push 更改检测,当路由发生(参数更改)时我们有一个this.ref.detectChanges(),它以某种方式破坏了路由(可能将并行运行的解析器踢出 ngZone 或类似的东西)。将其更改为无论如何首选后,this.ref.markForCheck()此错误不再出现。我很高兴我们不需要解决方法,但奇怪的行为..

希望这可以帮助任何有同样问题的人。

于 2019-02-21T08:25:56.277 回答
5

由于没有公认的答案,而且我发现,使用 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();
}

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

于 2020-02-17T06:46:00.787 回答
1

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

希望这可以帮助任何有同样问题的人。

于 2020-04-25T07:14:21.833 回答
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);
          });
        });
      }
于 2021-07-16T20:47:58.030 回答