使用 Behaviorsubject 时不会触发更改检测

Change detection is not triggered when using Behaviorsubject

我有两个同级组件,每个组件都通过正在服务的 Behaviorsubject 进行通信和发送数据。组件 AngOnInit 内订阅来自组件 B.

的数据

Component B 侦听来自 websoket 的消息,当消息到达时,我正在触发更新 Behaviorsubject value.So 的方法,当新日期从组件 B ,组件 A 必须显示确认模态,但模态未显示,因为即使我使用 angular 变化检测也没有被触发 Object.assign().

我哪里错了?

这是我的代码:

product.service.ts

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    
    @Injectable({
      providedIn: 'root'
    })
    
    export class ProductService {
    
      subjectProps: any = {
        showErrorModal: undefined,
        showSuccessfullyModal: undefined,
      };
    
      _subject$ = new BehaviorSubject(this.subjectProps);
      event = this._subject$.asObservable();
    
      constructor() { }
    
      updateSubjectProps(data: any) {
        this._subject$.next(data);
      };
    }

成功-modal.component.ts

 import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
    import { Subscription } from 'rxjs';
    import { ProductService } from '../../../services/product-catalogue.service';
    
    @Component({
      selector: 'successfully-modal',
      templateUrl: './successfully-modal.component.html',
      styleUrls: ['./successfully-modal.component.scss']
    })
    
    export class ImportCompletedSuccessfullyModalComponent implements OnInit, OnDestroy {
      showErrorModal: boolean = false;
      showSuccessfullyModal: boolean = false;
    
      productSubscription: Subscription
    
      constructor(private productService: ProductService) { }
    
      ngOnInit(): void {
        this.productSubscription = this.productService.event.subscribe(data => {
          if (data) {
            // Here I need to open successflully confirmation modal
            this.showSuccessfullyModal = data.showSuccessfullyModal;
          }
        });
      }
    
      ngOnDestroy(): void {
        if (this.productSubscription) {
          this.productSubscription.unsubscribe();
        }
      }
    
    }

products.component.ts

import { Component, OnDestroy, OnInit } from '@angular/core';
import { ProductService } from './services/product-catalogue.service';
import { Subscription } from 'rxjs';
import { webSocketListener } from '../../../event-bus';


@Component({
  selector: 'products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.scss']
})

export class MigrationToolComponent implements OnInit, OnDestroy {
  subjectProps: any;
  productSubscription: Subscription
  isLoading: boolean;
  products: any[] = [];

  constructor(private productService: ProductService) { }

  ngOnInit(): void {
    this.fetchProducts();

    this.productSubscription = this.productService.event.subscribe(data => {
      this.subjectProps = data;
    });

    webSocketListener.on((message: any) => {
      this.checkProductStatus(message);
    });
  }

  fetchProducts(): void {
    this.isLoading = true;
    this.productService.getProducts().subscribe(res => {
      this.isLoading = false;
      this.products = res.products;
    }),
      error => {
        this.isLoading = false;
        console.log(error);
      }
  }

  checkProductStatus(message: string) {
    let subjectProps = Object.assign({}, this.subjectProps);

    if (message === 'failed') {
      subjectProps.showErrorModal = true;
      subjectProps.showSuccessfullyModal = false;
    }

    if (message === 'success') {
      subjectProps.showSuccessfullyModal = true;
      subjectProps.showErrorModal = false;
    }

    this.productService.updateSubjectProps(subjectProps);
    this.fetchProducts();
  }

  ngOnDestroy(): void {
    if (this.productSubscription) {
      this.productSubscription.unsubscribe();
    }
  }

}

这与 webSocketListener(可能)在 angular 之外工作有关。您应该在 angular 中调用 checkProductStatus 函数,您可以使用 NgZone service this.

import { Component, OnDestroy, OnInit, NgZone } from '@angular/core';
import { ProductService } from './services/product-catalogue.service';
import { Subscription } from 'rxjs';
import { webSocketListener } from '../../../event-bus';

@Component({
  selector: 'products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.scss'],
})
export class MigrationToolComponent implements OnInit, OnDestroy {
  constructor(private productService: ProductService, private ngZone: NgZone) {}

  ngOnInit(): void {
      webSocketListener.on((message: any) => {
          this.ngZone.run(() => {
              this.checkProductStatus(message);
          });
    });
  }
}