如何让Mat-Table观察其数据源的变化

时间:2018-09-07 20:49:54

标签: angular typescript rxjs

我用角cli创建了一个角6项目。

在用户界面中使用角度材质

我正在开发某种电子商务应用程序,因此我使用以下代码创建了购物车服务:

import {Inject, Injectable} from '@angular/core';
import { LOCAL_STORAGE, StorageService } from 'ngx-webstorage-service';
import {Product} from './product';
import {CartProduct} from './CartProduct';



const CART_ITEMS = 'cart_items';

@Injectable({
  providedIn: 'root'
})
export class CartService {
  cartItems: {};
  constructor(@Inject(LOCAL_STORAGE) private storage: StorageService) {
    if (!this.storage.has(CART_ITEMS)) {
      this.storage.set(CART_ITEMS, []);
      this.cartItems = {};
    } else {
      this.cartItems = this.storage.get(CART_ITEMS);
    }
  }

  public addProduct(product: Product, quantity: number) {
    if (this.cartItems.hasOwnProperty(product.id)) {
      this.cartItems[product.id].quantity += quantity;
    } else {
      const p: CartProduct = new CartProduct();
      p.product = product;
      p.quantity = quantity;
      this.cartItems[product.id] = p;
    }
    this.storage.set(CART_ITEMS, this.cartItems);
  }
  public setProductQuantity(productId: number, quantity: number): boolean {
    if (this.cartItems.hasOwnProperty(productId)) {
      this.cartItems[productId].quantity = quantity;
      this.storage.set(CART_ITEMS, this.cartItems);
      return true;
    } else {
      return false;
    }
  }
  public clearCart() {
    this.storage.remove(CART_ITEMS);
    this.cartItems = {};
  }

  public getCart() {
    const cartArray = [];
      for (const k of Object.keys(this.cartItems)) {
        cartArray.push(this.cartItems[k]);
      }
      return cartArray;
  }

  public removeProduct(productId: number): boolean {
    if (this.cartItems.hasOwnProperty(productId)) {
      delete this.cartItems[productId];
      this.storage.set(CART_ITEMS, this.cartItems);
      return true;
    } else {
      return false;
    }
  }
}

我实现了getCart()函数,该函数将对象转换为数组,以便将其作为DataSourcemat-table的形式提供。

我有一个Cart组件和一个Product组件,它们与购物车服务交互。

产品组件具有一个“添加产品”按钮,其中包含要指定的数量。 所以我用以下代码实现了它:

import {Component, Input, OnInit} from '@angular/core';
import {Product} from '../product';
import {CartService} from '../cart.service';

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.scss']
})
export class ProductComponent implements OnInit {

  public quantity: number;
  @Input() product: Product;
  constructor(private cart: CartService) {
    this.quantity = 1;
  }

  addToCart() {
    this.cart.addProduct(this.product, this.quantity);
  }

  ngOnInit() {
  }

}

在购物车组件中,我创建了一个删除产品功能

removeProduct(productId) {
    this.cart.removeProduct(productId);
    this.cartItems = this.cart.getCart();
  }

正如您在这里看到的,我实际上需要再次设置this.cartItems变量,以使ui刷新真正起作用。所以在这里,当我从呈现购物车的同一组件中将购物车中的产品移除时,刷新工作正常。

但是当我从产品组件添加产品时,我需要刷新浏览器中的页面,以查看新产品已添加到购物车产品列表中。

如何通知mat-table组件内的Cart组件DataSource已更改。就我而言,它是由Product组件更改的。

谢谢

1 个答案:

答案 0 :(得分:1)

一个主题(既是观察者又是可观察的对象)可以用来向应用程序中的订户发送购物车更改,而不论层次结构如何,只要他们注入了CartService。

https://stackblitz.com/edit/angular-xycmug

“推入”机制是理想的,因为您不必手动要求物品,并且仅当物品本身发生变化时才接收排放。