多个订阅角度 6

Posted

技术标签:

【中文标题】多个订阅角度 6【英文标题】:Multiple subscribe angular 6 【发布时间】:2018-10-04 09:47:44 【问题描述】:

我正在建立一个包含一些产品的电子商店。用户可以添加到购物车,他可以看到他添加的产品。我分为三类。一个类别是我显示所有产品的所有产品和一个我显示特定产品的水果和面包类别..一切正常但是当我更改类别而不单击添加到购物车按钮时,角度执行 addToCart 方法..我认为它是多个订阅和内存泄漏的问题..我怎样才能用更好的编码做到这一点?这是我的 ts 和 html 角度文件。

我的产品.ts

import Component, OnDestroy, OnInit from '@angular/core';
import CategoryService from '../category.service';
import ActivatedRoute from '@angular/router';
import Subject from 'rxjs/index';
import 'rxjs/add/operator/takeUntil';
import ShoppingCartService from '../services/shopping-cart.service';
import Product from '../models/product';




@Component(
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css'],

)
export class ProductsComponent implements OnInit, OnDestroy 

  products: any;
  filteredproducts: any;
  category: any;
  res: any;
  categoryid: any;
  cartId: any;
  private ngUnsubscribe: Subject<any> = new Subject();





  constructor(private service: CategoryService,
              private route: ActivatedRoute,
              private cartService: ShoppingCartService) 


  


ngOnInit() 

  this.route.queryParamMap.takeUntil(this.ngUnsubscribe).subscribe(params => 
    this.category = params.get('category');
    this.cartId = localStorage.getItem('cartId');
    if (this.category) 
        setTimeout(() => 
            this.service.allProductNames(this.category, this.cartId).takeUntil(this.ngUnsubscribe).subscribe(data => 
                this.filteredproducts = this.products = data;
            );
        , 500);

     else 
        if (this.cartId === null) this.cartId = -1; 
        setTimeout(() => 
            this.service.getProducts(this.cartId).takeUntil(this.ngUnsubscribe).subscribe(data => 
                this.filteredproducts = data;
            );
        , 500);


    

  );





    addToCart(products: Product) 

        const cartId = this.cartService.getOrCreateCartId();

        if (!cartId) 
         const imero = new Date().getTime();
         this.cartService.create(imero).takeUntil(this.ngUnsubscribe).subscribe(res => 
           this.res = res;
           localStorage.setItem('cartId', this.res.id);
           this.route.queryParamMap.takeUntil(this.ngUnsubscribe).subscribe(params => 
           this.categoryid = params.get('category');
           if (this.categoryid) 
            this.cartService.createItem(products.id, this.res.id).
            takeUntil(this.ngUnsubscribe).subscribe(res1 => 
                setTimeout(() => 
                    this.service.allProductNames(this.category, this.res.id).takeUntil(this.ngUnsubscribe).subscribe(data => 
                        this.filteredproducts = this.products = data;);
                , 500);

            );

            else 
           this.cartService.createItem(products.id, this.res.id).takeUntil(this.ngUnsubscribe).subscribe(res2 => 
               setTimeout(() => 
                   this.service.getProducts(this.res.id).takeUntil(this.ngUnsubscribe).subscribe(data => 
                       this.filteredproducts = data;
                   );
               , 500);

            );
              

                );
            );

        


        else 
            this.route.queryParamMap.takeUntil(this.ngUnsubscribe).subscribe(params => 
                this.categoryid = params.get('category');
                this.cartId = localStorage.getItem('cartId');
                if (this.category) 
                    this.cartService.createItem(products.id, this.cartId).takeUntil(this.ngUnsubscribe).subscribe(res1 => );
                    setTimeout(() => 
                        this.service.allProductNames(this.category, this.cartId).takeUntil(this.ngUnsubscribe).subscribe(data => 
                            this.filteredproducts = data;
                            );

                    , 500);

                 else 
                    this.cartService.createItem(products.id, this.cartId).takeUntil(this.ngUnsubscribe).subscribe(res1 => );
                    setTimeout(() => 
                        this.service.getProducts(this.cartId).takeUntil(this.ngUnsubscribe).subscribe(data => 
                            this.filteredproducts = data;
                            console.log(this.products););

                    , 500);
                





            );

        
    



ngOnDestroy() 
  this.ngUnsubscribe.next();
  this.ngUnsubscribe.complete();



我的产品.html

<div class="row">
  <div class="col-sm-3">
<app-product-filter></app-product-filter>
  </div>
  <div class="col-sm-9">
    <div class="row">
      <ng-container  *ngFor="let p of filteredproducts; let i = index">
        <div class="col">
            <div class="card">
                <img  class="card-img-top" src="p?.imageUrl" style="max-height: 200px; width: 100%;">
                <div class="card-body">
                    <h5 class="card-title">p?.title</h5>
                    <p class="card-text">p?.price | currency: 'EUR': symbol </p>
                </div>
                <div class="card-footer">
                    <button (click)="addToCart(p)" class="btn btn-primary btn-block">Add to Cart</button>
                    <div *ngIf="p?.quantity!=0">p?.quantity</div>
                </div>
            </div>

        </div>
        <div *ngIf="(i+1) % 2 === 0" class="w-100"></div>
      </ng-container>

    </div>
  </div>
</div>

【问题讨论】:

【参考方案1】:

您永远不应该订阅订阅。您可以像这样更改代码:

this.route.queryParamMap.mergeMap(params => 
    this.category = params.get('category');
    this.cartId = localStorage.getItem('cartId');
    if (this.category) 
       return this.service.allProductNames(this.category, this.cartId);
     else 
        if (this.cartId === null) 
           this.cartId = -1;
        
        return this.service.getProducts(this.cartId);    
    
  ).takeUntil(this.ngUnsubscribe).subscribe(data => this.filteredproducts = data);

您应该只订阅一次 queryParams,它应该在 ngOnInit 中。这些是您在添加到购物车方法中应考虑的以下几点:

    您已经在方法中声明了类别属性使用它。不要订阅 queryParams。 使用mergeMap rxjs 运算符删除嵌套订阅。 当组件销毁时,嵌套订阅不会取消订阅。 您不应在订阅中使用 setTimeout。使用 debounceTime rxjs 运算符

【讨论】:

谢谢 :) 我正在尝试修复 addToCart 方法,但使用 mergeMap,并且里面的代码不起作用..我的程序没有进入..我遵循相同的逻辑..在 ngOnInit 内部一切正常,但在 mergeMap 外部似乎不起作用:( 我修好了..非常感谢您的帮助

以上是关于多个订阅角度 6的主要内容,如果未能解决你的问题,请参考以下文章

以角度6动态加载formarray中的多个下拉列表

如何在角度 6 中显示多个行值的总数以分隔表格的列?

如何处理角度 6 中的多个 mat-slide-toggle 标签?

多个独立的 websockets 连接

学习指南!kafka订阅多个topic

第三章Redis消息队列