如何在通过 Angular 中的服务发送的接收组件中堆叠值?

Posted

技术标签:

【中文标题】如何在通过 Angular 中的服务发送的接收组件中堆叠值?【英文标题】:How can I stack values in receiving component that is being sent through a service in Angular? 【发布时间】:2019-09-26 14:10:45 【问题描述】:

我正在制作简单的网上商店,使用 BehaviorSubject 和 observable 将电影从“产品组件”通过“购物车服务”发送到“购物车组件”。

它工作正常,但我只发送一部电影,当我按“购买”时,它总是用正在发送的新对象替换旧电影。

我基本上到处都尝试过 ++ 或 += 之类的东西,但它无法编译。

产品-组件:

import  Component, OnInit, Input, HostListener  from '@angular/core';
import  IMovie  from '../interfaces/IMovie';
import  CartService  from '../services/cart.service';

@Component(
  selector: 'app-display-movie',
  templateUrl: './display-movie.component.html',
  styleUrls: ['./display-movie.component.scss']
)

export class DisplayMovieComponent implements OnInit 
   @Input() movie: IMovie;

   message: string;

   constructor(private cartservice: CartService)  

   ngOnInit() 
   

  addToCart(movie)
    this.cartservice.updateCart(movie);
    localStorage.setItem("cart", JSON.stringify(movie));
  



HTML

 <button (click)="addToCart(movie)" class="btn-add">Buy</button>

服务:

import  Injectable, Output, EventEmitter  from '@angular/core';
import  IMovie  from '../interfaces/IMovie';
import  BehaviorSubject  from 'rxjs';
import  Subject  from 'rxjs';

@Injectable()
export class CartService 

  private cartSource = new BehaviorSubject<any[]>([]);

  currentShoppingCart = this.cartSource.asObservable();

  constructor()

  updateCart(item: any[])
    this.cartSource.next(item);

  

购物车组件

import  Component, OnInit, Input  from '@angular/core';
import  CartService  from '../services/cart.service';
import  IMovie  from '../interfaces/IMovie';

@Component(
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.scss']
)
export class CartComponent implements OnInit 
  message: string;
  item: IMovie[];

  constructor(private cartservice: CartService) 

  ngOnInit() 
  this.cartservice.currentShoppingCart.subscribe(item => this.item = item)
  

我希望购物车将项目堆叠为一个数组,然后在购物车组件视图中显示该数组。

【问题讨论】:

【参考方案1】:

Re '++' 和 '+=' 您只能将它们与数字一起使用,因此它们对数组或可观察对象没有太大帮助。 要向数组添加项目,您可以使用 myArray.push(item) 将项目添加到末尾,或者使用 myArray.unshift(item) 将项目添加到数组的开头。

一般建议 - 如果您的属性包含数组 - 就像您的 'item: IMovie[]' 最好将其命名为 'items: IMovie[]'。

如果 CartService 有一个属性“购物车”,则可能解决您的问题的一个可能的方法 - 这将是电影数组。 然后,“addMovie”方法会将当前选定的电影添加到该数组中,并使用 BeaviorSubject 的“next”方法广播该新数组。

export class CartService 
    private cartSource = new BehaviorSubject<any[]>([]);
    private cart: IMovie[] = []

    currentShoppingCart = this.cartSource.asObservable();  

    addMovie(movie: IMovie)
        this.cart.push(movie);
        this.cartSource.next(this.cart);
    



export class CartComponent implements OnInit 
    items: IMovie[];

    constructor(private cartservice: CartService) 

    ngOnInit() 
        this.cartservice.currentShoppingCart.subscribe(items => this.items = items)
    

【讨论】:

非常感谢,它正在工作!现在我只需要以某种方式访问​​这个数组数据,例如在我的 HTML 中打印 items.name 时,我得到了 Object Object。我需要以特殊方式循环显示它吗? 我也解决了!我用 *ngFor 遍历了这些项目。你会说总体来说这是一个购物车的好解决方案吗? 如何防止相同的对象一个接一个地堆叠?假设我买了 2 个相同的东西,我希望它显示 2x Interstellar,而不是 Interstellar、Interstellar 等等? 没问题。一种可能的解决方案是将购物车项目存储在字典中(其中键将是电影 ID 的对象)。看看这里:stackblitz.com/edit/angular-nthmtz 成功了,谢谢!唯一的问题是 map 函数为购物车项目提供了新的 id(我的电影 id 列表从 64 开始)。当我将每个新项目保存到本地存储时,这将是一个问题,因为 id 不匹配。在 localstorage 中,ID 为 64、65 等,购物车中的 id 为 0、1、2 等。我该如何解决?

以上是关于如何在通过 Angular 中的服务发送的接收组件中堆叠值?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 8:将表单数据作为服务发送到另一个组件

如何将从服务接收到的 json 数据传递到 Angular 4 的角材料组件中的数组

如何接收通过 HttpParams 发送的参数

如何从 ngOnInit Angular 中的服务获取数据

Angular 2:如何在组件将观察更改的服务中创建一个数组?

如何在Angular中的路由组件之间传递数据