1. ホーム
  2. angular

[解決済み] 他のコンポーネントから更新されたときに、サービス変数の変更を検出するにはどうしたらいいですか?

2023-08-07 11:50:31

質問

サービス変数から更新された値を取得しようとしています( isSidebarVisible ) から更新された値を取得したいのですが、 これは別のコンポーネント ( header ) によって更新され続け、クリックイベント ( toggleSidebar ).

sidebar.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable() 
export class SidebarService {
    isSidebarVisible: boolean;

    sidebarVisibilityChange: Subject<boolean> = new Subject<boolean>();

    constructor()  {
        this.isSidebarVisible = false;
    }

    toggleSidebarVisibilty() {
        this.isSidebarVisible = !this.isSidebarVisible
        this.sidebarVisibilityChange.next(this.isSidebarVisible);
    }
}

サイドバー.コンポーネント.ts

export class SidebarComponent implements OnInit {
    asideVisible: boolean;
    _asideSubscription: any;

    constructor(private sidebarService: SidebarService) {
        this.asideVisible = sidebarService.isSidebarVisible
        this._asideSubscription = sidebarService.sidebarVisibilityChange.subscribe((value) => {
            this.asideVisible = value
        })
    }
    
    ngOnInit() {
    }
}

header.component.ts(サービス変数が更新される場所)

export class HeaderComponent implements OnInit {
    isSidebarVisible: boolean;
    _subscription: any;

    constructor(private sidebarService: SidebarService) {
        this._subscription = sidebarService.sidebarVisibilityChange.subscribe((value) => {
            this.isSidebarVisible = value
        })
    }

    toggleSidebar() {
        this.sidebarService.toggleSidebarVisibilty()
    }

    ngOnInit() {

    }
}

でサービス変数の値が変化しているのがわかります. header.component.html というときに {{ isSidebarVisible }} しかし sidebar.component.html では常にデフォルト値が表示され、変更に耳を傾けることはありません。

これを修正するのを助けてください。

どのように解決するのですか?

サブスクリプションをサービスに移動させ、両方のコンポーネントがこの値にアクセスできるようにします。もし値が一度だけ必要なら、直接それを使うことができます (私が サイドバー.コンポーネント でやったように); もしこの値で何かを更新する必要があるなら、ゲッターを使うことができます(例えば header.component ).

sidebar.service.ts。

@Injectable() 
export class SidebarService {
    isSidebarVisible: boolean;

    sidebarVisibilityChange: Subject<boolean> = new Subject<boolean>();

    constructor()  {
        this.sidebarVisibilityChange.subscribe((value) => {
            this.isSidebarVisible = value
        });
    }

    toggleSidebarVisibility() {
        this.sidebarVisibilityChange.next(!this.isSidebarVisible);
    }
}

サイドバー.コンポーネント.ts

export class SidebarComponent {
    asideVisible: boolean;

    constructor(private sidebarService: SidebarService) {
        this.asideVisible = sidebarService.isSidebarVisible;
    }
}

ヘッダーコンポーネント.ts

export class HeaderComponent {
    constructor(private sidebarService: SidebarService) { }

    get isSidebarVisible(): boolean {
        return this.sidebarService.isSidebarVisible;
    }

    toggleSidebar() {
        this.sidebarService.toggleSidebarVisibility()
    }
}

また、どちらか/両方のコンポーネントでサブジェクトを購読し、そこで値を取得することも可能です。

this.sidebarService.sidebarVisibilityChange.subscribe(value => {...});

もし、Subjectsについてもっと知りたいのであれば をご覧ください。 .