【问题标题】:Not receiving variable value from service in Angular未从 Angular 中的服务接收变量值
【发布时间】:2020-05-21 23:51:56
【问题描述】:

我在我的应用程序中开发了一个 cookie 检查器服务,它应该检查我的 cookie 同意弹出窗口的状态:

@Injectable()
export class CookieCheckService implements OnInit, OnDestroy {
  public hasConsented = false;
  private cookieStatusChangeSubscription: Subscription;

  constructor(
    private ccService: NgcCookieConsentService
  ) {
  }

  ngOnInit() {
    if (this.ccService.hasConsented()) {
      this.hasConsented = true;
    }

    console.log(this.hasConsented);

    this.cookieStatusChangeSubscription = this.ccService.statusChange$.subscribe(
      (event: NgcStatusChangeEvent) => {
        this.hasConsented = event.status === this.ccService.getStatus().allow;
      });
  }

  ngOnDestroy() {
    this.cookieStatusChangeSubscription.unsubscribe();
  }
}

我的想法是现在从我需要检查状态的任何组件中调用它,例如在我显示 Google 地图的页脚中:

@Component({
  selector   : 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls  : ['./footer.component.css']
})
export class FooterComponent {
  hasConsented = false;

  constructor(
    private cookieCheckService: CookieCheckService
  ) {
    this.hasConsented = cookieCheckService.hasConsented;
  }
}

通常,当我现在按允许时,我想通过ngIf 使我的 Google 地图小部件可见,但不知何故,我没有从我的服务中获得任何价值 - 最初也是如此。我在这里做错了什么?

更新

因为有人问:this.ccService.getStatus()是一个返回的接口:

export interface NgcCookieConsentStatus {
    allow?: 'allow';
    deny?: 'deny';
    dismiss?: 'dismiss';
}

【问题讨论】:

  • @Sajeetharan 添加了一个更新来解释您的评论。
  • 组件中的hasConsented是做什么用的?
  • @ConnorsFan 正如我的问题中所述,我在 ngIf 中使用它来显示/隐藏内容。

标签: angular typescript


【解决方案1】:

我看到了两个问题

  1. OnInit()OnDestroy() 等生命周期钩子适用于组件和指令。它们不适用于服务。

  2. 服务中的this.hasConsented 是异步分配的。您可能必须改变行为。但为了快速解决问题,您可以将所有内容移至构造函数。

试试下面的

服务

@Injectable()
export class CookieCheckService {
  public hasConsented = false;
  private cookieStatusChangeSubscription: Subscription;

  constructor(private ccService: NgcCookieConsentService) {
    if (this.ccService.hasConsented()) {
      this.hasConsented = true;
    }

    console.log(this.hasConsented);

    this.cookieStatusChangeSubscription = this.ccService.statusChange$.subscribe(
      (event: NgcStatusChangeEvent) => { this.hasConsented = event.status === this.ccService.getStatus().allow; }
    );
  }
}

更新

要在组件中反映对 hasConsented(服务)的更改,您可以将其设为 RxJS BehaviorSubject。您还可以将{ providedIn: 'root' } 提供给服务的@Injectable 装饰器,以确保它是singleton(整个应用程序中的一个服务实例)。

服务

import { BehaviorSubject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class CookieCheckService {
  private hasConsentedSource = new BehaviorSubject<boolean>(false);

  public get hasConsented() {
    return this.hasConsentedSource.asObservable();
  }

  constructor(private ccService: NgcCookieConsentService) {
    if (this.ccService.hasConsented()) {
      this.hasConsentedSource.next(true);
    }

    console.log(this.hasConsented);

    this.ccService.statusChange$.subscribe(
      (event: NgcStatusChangeEvent) => { 
        this.hasConsentedSource.next(event.status === this.ccService.getStatus().allow); 
      }
    );
  }
}

然后就可以在组件中订阅了。

组件

@Component({
  selector   : 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls  : ['./footer.component.css']
})
export class FooterComponent {
  hasConsented = false;

  constructor(private cookieCheckService: CookieCheckService) {
    this.cookieCheckService.hasConsented.subscribe(
      status => { this.hasConsented = status }
    );
  }
}

现在每次将新值推送到服务中的hasConsented 值时,组件中的hasConsented 值都会更新。

【讨论】:

  • 它是否也注册了更改并将其返回给组件?我是否需要以某种方式销毁 ccService 上的订阅?
  • 您是否希望每次在服务中更改 hasConsented 的值时将其推送到组件?
  • 是的,就是这样。为了您的理解,我是 Angular 和 TS 的新手。因此,如果我再次按下拒绝或接受,它想显示/隐藏通过 ngIf 检查的所有内容。
  • 我喜欢它!非常感谢你的帮助。它的工作真棒!
  • 我不认为我理解这个问题。但是如果我找到方法会发布。
猜你喜欢
  • 2020-06-13
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 2018-06-03
相关资源
最近更新 更多