ค้นหาเว็บไซต์

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