angular - การสมัครใช้งาน Directive ไม่ทำงานแม้ว่าวิชา (subject) จะเรียก next
Plunkr: https://plnkr.co/edit/KfPfVSbZm087uIPvFEkM?p=preview
ฉันมีบริการซึ่งทำหน้าที่เป็น API สำหรับคอมโพเนนต์โมดอล และฉันก็มีไดเร็กทีฟซึ่งสามารถใช้เพิ่มคลาสให้กับองค์ประกอบใดก็ได้เมื่อโมดอลเปิดอยู่ อย่างไรก็ตาม การสมัครสมาชิกภายในไดเร็กทีฟไม่ทำงานไม่ว่าจะทำอย่างไร
ฉันได้ลองใช้ทั้ง Subject และ BehaviorSubject แต่ไม่มีอันไหนใช้งานได้
บริการ :
@Injectable()
export class ModalApiService {
constructor() {}
private states = new Subject<any>();
states$ = this.states.asObservable();
open(id: string, template?: string): void {
this.states.next({isOpen: true, id: id, template: template});
// This runs as expected
console.log(true);
}
close(id: string): void {
this.states.next({isOpen: false, id: id});
}
}
คำสั่ง:
@Directive({
selector: '[modalState]'
})
export class ModalStateDirective implements OnDestroy, OnInit {
constructor(private modalApi: ModalApiService) {}
private modalSubscription: Subscription;
@HostBinding('class.modal-open')
isOpen: boolean;
ngOnInit() {
this.modalSubscription = this.modalApi.states$.subscribe(
state => {
this.isOpen = state.isOpen;
console.log(this.isOpen)
}
);
}
ngOnDestroy() {
this.modalSubscription.unsubscribe();
}
}
คำตอบ #1
ถ้าคุณใช้ BehaviourSubject มันทำงานได้และจะเข้าถึง subscribe function แต่ยังไม่สามารถระบุได้ว่าทำไมเราถึงมี undefined value ของ object properties เมื่อฉันสามารถบันทึกวัตถุได้อย่างถูกต้อง
import 'rxjs/Rx';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
private states = new BehaviorSubject<any>();
states$ = this.states.asObservable();
ทำงานแต่ไม่ทำงาน : https://plnkr.co/edit/YspSd2fKvktPEk6bL2hF?p=preview
คำตอบ #2
การสมัครรับข้อมูลไม่ทำงาน เพราะคำสั่ง ngOnInit ของ directive ถูกเรียกหลังจาก ngOnInit ของแอป ดังนั้น next จะถูกเรียก ก่อนการสมัครรับข้อมูลใน directive สิ่งนี้สามารถพิสูจน์ได้ด้วยปุ่มง่าย ๆ ที่เรียกใช้เมธอดเปิด/ปิดของ service:
toggle() {
this.modalApi.open('someid');
this.modalApi.close('someid');
}
ตัวอย่าง: https://plnkr.co/edit/MJET0Jw12SLx0BChAiWz?p=preview
หากคุณจริง ๆ ต้องการเริ่มต้นด้วยการสนทนาแบบเปิดโดยใช้บริการนี้ ฉันก็ขอแนะนำให้คุณใช้ ReplaySubject ซึ่งจะให้คุณได้รับการส่งสัญญาณทั้งหมดก่อนการสมัครสมาชิกครั้งแรก:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/replaysubject.md
นี่คือตัวอย่างการใช้งาน ReplaySubject:
https://plnkr.co/edit/boHGQhc7atMTOTPLMnO0?p=preview
