使用行为可能会触发更改检测

发布于 2025-01-21 21:48:51 字数 3864 浏览 1 评论 0原文

我有两个兄弟姐妹组件每个兄弟姐妹通过在使用中的行为主体传达并发送数据。组件 a ngoninit 内订阅了来自组件 b 的数据。

组件 b 聆听来自WebSoket的消息,当消息到达时,iM触发方法会更新cistion usubject value。 strong> a 必须显示确认模态,但未显示模态,因为即使我使用 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);
      };
    }

成功地莫达尔

 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();
        }
      }
    
    }

.component.tsproducts.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();
    }
  }

}

I have two sibling components each one communicates and send data through Behaviorsubject which is in service. Component A is subscribe inside ngOnInit for data coming from component B.

Component B Listen for message coming from websoket , when the message arrives I`m triggering method which updates the Behaviorsubject value.So when the new date arrives from component B , component A must shown confirmation modal but the modal is not showning because angular change detection is not being triggered even if I use Object.assign().

Where am I wrong ?

Here is my code:

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);
      };
    }

successfully-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();
    }
  }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嗫嚅 2025-01-28 21:48:51

这与Angular之外的WebSocketListener(可能)相关。您应该在Angular中调用CheckProductStatus函数,可以使用 ngzone 为此服务。

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);
          });
    });
  }
}

This is related to the webSocketListener (probably) works outside of angular. You should call checkProductStatus function in angular, you can use 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);
          });
    });
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文