简体   繁体   English

角度:应用程序组件未检测到子组件的更改

[英]Angular: App Component not detecting change of Child Component

I'm building a shopping cart, and everything is working fine except when the website first load, if the person doesn't have a shopping cart saved, they have to click add to cart before one is made. 我正在构建一个购物车,除了网站首次加载时,其他一切工作正常,如果该人没有保存购物车,则他们必须在创建购物车之前单击添加到购物车。 The problem is, my app.component doesn't realize that local storage is updated until the page is refreshed. 问题是,我的app.component直到刷新页面后才意识到本地存储已更新。 I've been working on this for 3 days and cant seem to figure it out. 我已经为此工作了3天,似乎无法弄清楚。 I tried to refresh the page after the button is clicked, but that resulted in some of my functions not being called at all. 单击按钮后,我尝试刷新页面,但是这导致我的某些功能根本没有被调用。 I read about subjects and behavior variables. 我阅读了有关主题和行为变量的文章。 It didn't seem to correspond with what it is I feel I need. 它似乎不符合我的需求。 To my understanding, a subject or behavior variable requires subscribing to an observable, but I don't need to subscribe to anything in this instance. 据我了解,主题或行为变量需要订阅可观察对象,但是在这种情况下,我不需要订阅任何内容。 I just need to know when local storage is updated in real time. 我只需要知道本地存储何时实时更新。 The only relevant piece of code is the code in app.component.ts because it is the code that is manipulating the cart total and count. 唯一相关的代码是app.component.ts中的代码,因为它是操纵购物车总计和计数的代码。 I added the other piece of code just in case that may be a problem. 我添加了另一段代码,以防万一可能是个问题。 Any help would be greatly appreciated, thanks 任何帮助将不胜感激,谢谢

app.component.ts app.component.ts

id: localStorage.getItem('cartId');

        if(this.id){
         this.dbList =  db.list('/shopping-carts/' + this.id).valueChanges().subscribe(items => {
            this.dbTotal = items[items.length - 1];
            this.dbCartCount = items.length - 2;
            console.log('total and cart count updated...');
          });

        } 

clotheslist.component.ts Clotheslist.component.ts

addToCart(product, price){
  let cartId = localStorage.getItem('cartId');

  if(!cartId){
    this.cartService.create().then(result => {
      localStorage.setItem('cartId', result.key);
      this.cartService.pushProductToCart(product, price);
      this.cartService.cartTotal(price);
    });
  //add product to cart
  } else {
  this.cartService.pushProductToCart(product, price);
  this.cartService.cartTotal(price);
  }
}

I would consider making an event bus implemented as an Angular service. 我会考虑将事件总线实现为Angular服务。 You would use the RxJs Subject for this. 您将为此使用RxJs主题。

AppEventService: AppEventService:

@Injectable()
export class AppEventService {
  private eventBus: Subject<string> = new Subject<string>();
  public events: Observable<string> = this.eventBus.asObservable();

  constructor() {}

  publishEvent(eventName: string) {
    this.eventBus.next(eventName);
  }
}

clothes-list.component.ts Clothes-list.component.ts

addToCart(product, price){
  let cartId = localStorage.getItem('cartId');

  if(!cartId){
    this.cartService.create().then(result => {
      localStorage.setItem('cartId', result.key);
      this.cartService.pushProductToCart(product, price);
      this.cartService.cartTotal(price);
      //add product to cart
      this.eventsService.publishEvent('cart-updated');
    });
  } else {
  this.cartService.pushProductToCart(product, price);
  this.cartService.cartTotal(price);
  }
}

Finally, in app.component.ts: 最后,在app.component.ts中:

@Component(...)
export class AppComponent {
   constructor(..., private eventsService: AppEventsService) {}

   ngOnInit() {
      this.eventsService.events
        .filter(eventName => eventName === 'cart-updated')
        .subscribe(this.handleCartChange.bind(this));
   }

   handleCartChange() {
      // execute your logic to update the cart total and item count here
   }
}

Notice that you likely have to use the JS bind function when providing the observer (subscribe) to retain the context to the component class instance. 请注意,在提供观察者(订阅)以将上下文保留到组件类实例时,您可能必须使用JS绑定函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM