4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【RxJS】BehaviorSubject

Last updated at Posted at 2022-07-20

BehaviorSubjectでのデータ共有について、前提としてSubjectの理解もあった方が分かりやすかったため、併せて整理します。

Subjectとは

  • SubjectObservableによる値の購読とObserverによる値を受け取り実行する、両方の機能を持つオブジェクト。
  • ObservableではObserverにユニキャストで値を送信していたが、SubjectではObserverにマルチキャストで値を送信できる。
  • SubjectではObservableにてコンシューマーに値を送信していたsubscriber関数が不要。

Observable(ユニキャスト)

import { Observable } from 'rxjs';

const observable = new Observable(subscriber => {
  subscriber.next("hoge");
  subscriber.next("fuga");
  subscriber.next("piyo");
});

observable.subscribe({
  next: (v) => console.log(`observer1: ${v}`),
});

observable.subscribe({
  next: (v) => console.log(`observer2: ${v}`),
});

// 表示 (observer1,observer2が直列で実行される)
// observer1: hoge
// observer1: fuga
// observer1: piyo
// observer2: hoge
// observer2: fuga
// observer2: piyo

Subject(マルチキャスト)

import { Subject } from 'rxjs';

const subject = new Subject<string>();

subject.subscribe({
  next: (v) => console.log(`observer1: ${v}`),
});

subject.subscribe({
  next: (v) => console.log(`observer2: ${v}`),
});

subject.next("hoge");
subject.next("fuga");
subject.next("piyo");

// 表示 (observer1,observer2が並列で実行される)
// observer1: hoge
// observer2: hoge
// observer1: fuga
// observer2: fuga
// observer1: piyo
// observer2: piyo

BehaviorSubjectとは

  • Subjectの機能に加え、最後に更新された値を保持することができるオブジェクト。
  • コンストラクタにより初期値を設定することもできる。
  • 値を保持することができるため、コンポーネント間でデータ共有も可能。
import { BehaviorSubject } from 'rxjs';

// 初期値を0で設定
const subject = new BehaviorSubject(0);

subject.subscribe({
  next: (v) => console.log(`observer1: ${v}`),
});

subject.next(1);
subject.next(2);

subject.subscribe({
  next: (v) => console.log(`observer2: ${v}`),
});

subject.next(3);

// 表示
// observer1: 0
// observer1: 1
// observer1: 2
// observer2: 2 ※最新の値を保持しているため、observer2は値2が送信された後でも受信できる
// observer1: 3
// observer2: 3

値を別コンポーネントで共有する場合

各ファイルの役割

  • app.service.ts
    • 初期値の設定
    • 値の更新
  • app.component.ts
    • 値の購読
  • app.component.html
    • 値の表示

serviceのBehaviorSubjectを変更すると別コンポーネントでも値が更新されます。

app.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AppService {
 // 初期値の設定
  public name = new BehaviorSubject<string>("test");
  constructor() { }

  changeName(name: string): void {
    // 値の更新
    this.name.next(name);
  }
}
app.component.ts
import { Component, OnInit } from '@angular/core';
import { AppService } from './app.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit{
  public name: string = "";

  constructor(private appService: AppService) {}

  ngOnInit(){
    // 値の購読
    this.appService.name.subscribe(name => {
      this.name = name;
    });
  }

  changeName(name: string): void {
    this.appService.changeName(name);
  }
}
app.component.html
<!-- 値の表示 -->
<p>{{name}}</p> 
<input type="text" #newName>
<button (click)="changeName(newName.value)">名前変更</button>

参考

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?