【问题标题】:How can I stack values in receiving component that is being sent through a service in Angular?如何在通过 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)
  }
}

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

【问题讨论】:

    标签: angular service components interaction


    【解决方案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 等。我该如何解决?
    猜你喜欢
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 2017-08-04
    • 2020-12-19
    相关资源
    最近更新 更多