简体   繁体   中英

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. I've been working on this for 3 days and cant seem to figure it out. 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. 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

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

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. You would use the RxJs Subject for this.

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

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:

@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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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