Angular toSignal และ toObservable: เชื่อม RxJS กับ Signals
#angular12 เม.ย. 2569
ทำไมต้องเชื่อม RxJS กับ Signals
Angular มีทั้ง RxJS Observables และ Signals ซึ่งเป็น reactive system สองแบบ Angular 16+ มี utility functions สำหรับแปลงระหว่างกัน
toSignal() — Observable → Signal
import { toSignal } from '@angular/core/rxjs-interop';
import { inject } from '@angular/core';
@Component({
template: `
<p>{{ users() | json }}</p>
<p>{{ currentUser()?.name }}</p>
`
})
export class UserComponent {
private userService = inject(UserService);
private route = inject(ActivatedRoute);
// แปลง Observable เป็น Signal
users = toSignal(this.userService.getUsers(), {
initialValue: []
});
// จาก route params
userId = toSignal(this.route.params.pipe(map(p => p['id'])));
// computed จาก signal
currentUser = computed(() =>
this.users().find(u => u.id === this.userId())
);
}
toObservable() — Signal → Observable
import { toObservable } from '@angular/core/rxjs-interop';
@Component({ ... })
export class SearchComponent {
searchQuery = signal('');
// แปลง Signal เป็น Observable เพื่อใช้ RxJS operators
results = toSignal(
toObservable(this.searchQuery).pipe(
debounceTime(300),
distinctUntilChanged(),
filter(q => q.length >= 2),
switchMap(q => this.searchService.search(q))
),
{ initialValue: [] }
);
}
takeUntilDestroyed
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({ ... })
export class MyComponent {
constructor() {
// ไม่ต้องจัดการ unsubscribe เอง
this.userService.getUsers()
.pipe(takeUntilDestroyed())
.subscribe(users => this.users.set(users));
}
}
outputFromObservable
import { outputFromObservable } from '@angular/core/rxjs-interop';
@Component({ ... })
export class TimerComponent {
private tick$ = interval(1000);
tick = outputFromObservable(this.tick$);
}
สรุป
toSignal และ toObservable เป็น bridge ระหว่าง RxJS และ Signals ช่วยให้ migrate code ทีละส่วนได้โดยไม่ต้อง rewrite ทั้งหมดครับ