【问题标题】:Change component attribute in location.onPopState() callback在 location.onPopState() 回调中更改组件属性
【发布时间】:2023-01-30 00:03:16
【问题描述】:

我试图在我的组件中设置一个标志,以了解该视图是否由用户单击浏览器的“上一页”按钮加载。

“fromBackButton”属性在组件中定义时设置为 false。

在构造函数中我有这段代码:

this.location.subscribe((popStateEvent: PopStateEvent) => {
  // Detect popstate
  if (popStateEvent.type === 'popstate') {
    this.fromBackButton = true;
  }
});

如果我将 console.log(this.fromBackButton) 放在 ngOnInit 或任何其他方法中,则值为 False。

我试过使用

this.changeDetectorRef.markForCheck();

this.changeDetectorRef.detectChanges();

将标志设置为“True”后,还尝试使用 ngZone.run(),但我得到了相同的结果

【问题讨论】:

    标签: angular


    【解决方案1】:

    问题是组件在导航时被重新初始化。因此,fromBackButton 字段在返回时设置为 true,并在新组件初始化时立即重置为 false。

    所以你需要创建一个服务来获得在导航周期中“存活”的东西。我的意思是这样的:

    import {Injectable, OnDestroy} from '@angular/core';
    import {Location} from '@angular/common';
    import {SubscriptionLike} from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class NavigationStateService implements OnDestroy {
      private _isFromBackButton = false;
    
      private locationSubscription: SubscriptionLike;
    
      constructor(private location: Location) {
        this.locationSubscription = this.location.subscribe((popStateEvent: PopStateEvent) => {
          // Detect popstate
          if (popStateEvent.type === 'popstate') {
            console.debug('fromBackButton NavigationStateService', popStateEvent);
            this._isFromBackButton = true;
          }
        });
      }
    
      get isFromBackButton(): boolean {
        return this._isFromBackButton;
      }
    
      clearFromBackButtonState() {
        this._isFromBackButton = false;
      }
    
      ngOnDestroy(): void {
        this.locationSubscription.unsubscribe();
      }
    }
    

    对应的组件示例:

    import {Component, OnInit} from '@angular/core';
    import {NavigationStateService} from '../navigation-state.service';
    
    @Component({
      selector: 'app-page1',
      templateUrl: './page1.component.html',
      styleUrls: ['./page1.component.css']
    })
    export class Page1Component implements OnInit {
      fromBackButton = false;
    
      constructor(private navigationStateService: NavigationStateService) { }
    
      ngOnInit(): void {
        this.fromBackButton = this.navigationStateService.isFromBackButton;
        this.navigationStateService.clearFromBackButtonState();
      }
    }
    

    但是 PopState Event 的美中不足的是:它在向前和向后导航时被同等地触发。但那是另一项任务。这可能是一个很好的起点:How do I retrieve if the popstate event comes from back or forward actions with the HTML5 pushstate?

    【讨论】:

      猜你喜欢
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 2019-12-26
      • 2018-07-21
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      相关资源
      最近更新 更多