【问题标题】:Get previous route Angular 7获取以前的路线Angular 7
【发布时间】:2019-05-12 15:38:09
【问题描述】:

我创建了一个小服务,我可以在其中存储路线更改。

import { Injectable } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Injectable()
export class RouteState {

  private previousUrl: string;
  private currentUrl: string;

  constructor(private router: Router) {
    this.currentUrl = this.router.url;
    router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {        
        this.previousUrl = this.currentUrl;
        this.currentUrl = event.url;
      };
    });
  }

  public getPreviousUrl() {
    return this.previousUrl;
  }    
}

但每次路由更改时,vars currentUrl 和 previousUrl 都是未定义的。我做错了吗?

【问题讨论】:

  • 你添加到 app.module 提供者列表了吗? , 一切正常????????
  • 您的代码在 RouteState 服务中按您的意愿工作,我认为您在调用 getPreviousUrl 函数时或在其他地方犯了错误。如果提供您的代码,那么我可以帮助您。
  • 问题是每次路由改变时,previousUrl都是未定义的。我没有保存价值。

标签: angular typescript angular7


【解决方案1】:

使用 Angular 的定位服务,它内置于 Angular 并从 '@angular/common' 导入,如下所示:

import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';

import { Hero }         from '../hero';
import { HeroService }  from '../hero.service';

@Component({
  selector: 'app-hero-detail',
  templateUrl: './hero-detail.component.html',
  styleUrls: [ './hero-detail.component.css' ]
})
export class HeroDetailComponent implements OnInit {
  @Input() hero: Hero;

  constructor(
    private location: Location
  ) {}

  goBack() {
    this.location.back();
  }   
}

然后使用 location.back() 转到上一页。这是一个工作示例:

https://stackblitz.com/angular/qvvrbgrmmda

【讨论】:

  • 如果您没有历史记录,这将不起作用。例如,如果您在新选项卡中打开页面。
【解决方案2】:

如果你只想要上一条路线,你可以像这样创建一个 observable

 public previousRoute$: Observable<string> = this.router.events.pipe(
   filter((e) => e instanceof RoutesRecognized),
   pairwise(),
   map((e: [RoutesRecognized, RoutesRecognized]) => e[0].url)
 );

现在您可以订阅这个 observable 并执行任何操作(确保在 OnDestroy 事件上取消订阅这个 observable。)

this.previousRoute$.subscribe(url => {
  //perform your action
});

注意:当用户进行第二次导航时,此 observable 将开始发出事件。

【讨论】:

  • 您不应该使用 getter 来执行此操作,因为 Angular 可能会多次调用它并产生内存泄漏。您应该在组件销毁生命周期中存储并取消订阅它
  • 如果你在 OnInit 钩子中订阅它,那么 Angular 只会调用它一次,因为它返回无限的 observable,你需要取消订阅它以避免我在上面括号中提到的任何内存泄漏。
  • @VikashDahiya 这是正确的,但也许其他开发人员不会按照预期的方式使用它。 @alexandre-rousseau 提出的论点非常重要,恕我直言。因此,我只想为它声明一个字段。 private subscription: Subscription; previousRoute$: Observable&lt;string&gt; = this.router.events.pipe(...); ngOnInit() { this.subscription = this.previousRoute$.subscribe(...) }
  • @alexandre-rousseau 和 HasBert 你是对的,我已经更新了答案。如果我们想在 html 模板中使用该 observable(也可能是其他场景),那么从 getter 返回 observable 不是一个好主意,因为它可能会多次调用它,从而导致对同一个 observable 的多次订阅。感谢您的建议。
【解决方案3】:

这是一种使用@angular/router获取上一条路线的方法

the original post 上查找更多信息

import { Injectable } from '@angular/core';
import { Router, RouterEvent, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

@Injectable({
    providedIn: "root"
})
export class PreviousRouteService {

    private previousUrl: string;
    private currentUrl: string;

    constructor(private router: Router) {

        this.currentUrl = this.router.url;
        this.previousUrl = null;

        this.router.events
                    .pipe(filter((event: RouterEvent) => event instanceof NavigationEnd))
                    .subscribe((event: NavigationEnd) => {
                        this.previousUrl = this.currentUrl;
                        this.currentUrl = event.urlAfterRedirects;
                        console.log("prev: ", this.previousUrl)
                        console.log("curr: ", this.currentUrl)
                    });

    }

    public getPreviousUrl() {
        return this.previousUrl;
    }

};

【讨论】:

    【解决方案4】:

    如果您不想使用 Angular 提供的定位服务,那么您可以尝试以下服务。

    // service to get prev route
    @Injectable()
    export class RouteBackService {
        public getPreviousUrl(routeArray): string {
            let prevRoute = '';
            for (let i = 0; i < routeArray.length - 1; i++) {
                if (routeArray[i].url._value[0].length > 0) {
                    prevRoute += routeArray[i].url._value[0].path + '/';
                } 
            }
            return prevRoute.slice(0, -1);
        }
    }
    
    // in the component from where you want to route back    
    export class YourComponent {
        constructor (private _aRoute: ActivatedRoute,
                       private _routeBack: RouteBackService
                       private _router: Router) {}
        goBack() {
            const prevRoute=this._routeBack.getPreviousUrl(this._aRoute.pathFromRoot);
            this._router.navigate([prevRoute]);
        }
    }
    

    【讨论】:

      【解决方案5】:

      这在 Angular 8 中适用于我:

      从路由器你可以用方法获取最后一次成功的导航

      const lastSuccessfulNavigation = router.getLastSuccessfulNavigation();
      

      该对象属于type Navigation,其中包含一个previousNavigation 属性,而该属性又属于相同的Navigation 类型。

      const previousNavigation = lastSuccessfulNavigation.previousNavigation; 
      

      之前的导航是type UrlTree,可以直接用navigateByUrl方法导航:

      router.navigateByUrl(previousNavigation);
      

      【讨论】:

      • getLastSuccessfulNavigation() 是自定义方法吗?我没有看到任何关于任何地方的文档。 Google 中只有 5 个结果,控制台告诉我这不是函数。
      • 是的,我也找不到这个方法。
      • 这是一个私有字段
      猜你喜欢
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 2018-04-07
      • 2020-11-16
      • 2020-03-11
      • 2023-03-24
      • 1970-01-01
      • 2014-02-25
      相关资源
      最近更新 更多