【问题标题】:how to let mat-table observe changes to it's datasource如何让 mat-table 观察其数据源的变化
【发布时间】:2018-09-07 20:49:54
【问题描述】:

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

在 UI 中使用角度材质

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

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() 函数,该函数将对象转换为数组,以便将其作为DataSource 提供给mat-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 刷新真正起作用。所以在这里,当我从呈现购物车的同一组件中从购物车中删除产品时,刷新工作。

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

如何通知Cart 组件内的mat-table 组件DataSource 已更改。在我的例子中,它被 Product 组件改变了。

谢谢

【问题讨论】:

  • 在我看来,在这里使用主题是一个不错的选择。
  • 你想要这样的东西吗? stackblitz.com/edit/…
  • @Wingnod - 正是我所需要的。非常感谢!想把它作为答案发布吗?
  • 很高兴你发现它很有用 :)
  • 太棒了!这是一个非常强大的库。如果您在使用 rxjs 文档时遇到问题,这是帮助我对这些概念感到更舒服的原因。无聊的时候可以读一读。 gist.github.com/staltz/868e7e9bc2a7b8c1f754

标签: angular typescript rxjs


【解决方案1】:

主体(观察者和可观察者)可用于向整个应用程序中的订阅者发送对购物车的更改,无论层次结构如何,只要他们注入 CartService。

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

on push 机制是理想的,因为您不必手动请求项目,并且只有在项目本身发生变化时才会收到排放。

【讨论】:

    猜你喜欢
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 2011-07-03
    • 2018-03-26
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多