获取以前的路线Angular 7

Posted

技术标签:

【中文标题】获取以前的路线Angular 7【英文标题】:Get previous route 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都是未定义的。我没有保存价值。 【参考方案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 个结果,控制台告诉我这不是函数。 是的,我也找不到这个方法。 这是一个私有字段

以上是关于获取以前的路线Angular 7的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 获取当前路线

Laravel 5.1-5.8 中以前的路线名称

如何获取当前路线

国内两家医院疑似遭比特币勒索;Angular 团队发布 2018 年路线图

Angular 5:用于导航到相同路线但参数不同的路线动画

Angular,在特定路线上构建的问题