什么是更好的方法以及如何实现将对象从一个嵌套组件发送到另一个嵌套组件

时间:2018-06-28 09:36:09

标签: javascript angular typescript angular-template angular-decorator

我正在开发有关产品的简单应用程序,基本上,当用户选择产品时,应将其发送到另一个保存产品的组件中。

总是选择一个产品,我从不发送列表!只能按项目逐项

因此,基本上,当我单击屏幕中间的任何产品(产品食品1,产品食品2,产品食品3 )时,应将其发送到屏幕的右侧也是分开的组件。

所以我的中间部分看起来像这样:

<div *ngFor="let product of products;" class="product-holder">
  <div id="product.id" class="product" [style.background]="'url('+ product.imgUrl +')'">
    <p class="product-price">{{product.mpc | number}}</p>
    <p class="product-title">{{product.title}}</p>
  </div>
</div>

还有打字稿代码:

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

  products: Article[];

  constructor(private _sharedService: SharedService) { }

  ngOnInit() {
    this._sharedService.getEventSubject().subscribe((param: any) => {
      if (param !== undefined) {
        this.theTargetMethod(param);
      }
    });
  }

  theTargetMethod(param) {
    // Here I am populating middle screen with products 
    this.products = param;
  }
}

现在,我将发布应收到产品的正确组件:

<div class="order-article">
  <div class="order-img"></div>
  <div class="order-title">
    <p>HERE I SHOULD WRITE ARTILE TITLE</p>
  </div>
  <div class="order-quantity pull-right">
    <span class="order-quantity-number">ARTICLE QUANTITY</span>
  </div>
</div>

export class ReceiptItemComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

因此,这个“正确”的组件应该从中间接收点击的产品,而我不知道该怎么做,我对@Input@Output装饰器以及{{1} },我猜这里@input和@output是正确的解决方案,因为我要一一发送?

但是我实际上不知道如何解决这个问题。

任何一种帮助都很棒

谢谢

在fjc帮助之后:

services

如您所见,伙计们:

1。)我添加了<div *ngFor="let product of products;" class="product-holder" (click)="addReceiptItem(article)"> <div id="product.id" class="product" [style.background]="'url('+ product.imgUrl +')'"> <p class="product-price">{{product.mpc | number}}</p> <p class="product-title">{{product.title}}</p> </div> </div> 方法

2。)此方法接受点击的产品:

addReceiptItem

3。)注入服务'addReceiptItem(receiptItem: Product) { this._sharedService.addReceiptItem(receiptItem); } '并在其中创建方法也称为'addReceiptItem'

4。)在我的服务中,我这样创建了_sharedServiceBehaviorSubject

4。)服务中的方法如下:

private receiptItem = new BehaviorSubject<any>(undefined);

此方法将点击的项目推送到一个数组中,该数组将被发送到显示产品的组件中

4.11)还添加了用于获取返回BehaviorSubject的数据的方法:

addReceiptItem(receiptItems: Product) {
    this.arr1.push(receiptItems);
    this.receiptItem.next(this.arr1);
  }

5。)显示产品的已编辑组件(在执行任何操作之前也发布了代码-空的打字稿文件),现在看起来像这样:

getReceiptItem(): BehaviorSubject<any> {
    return this.receiptItem;
  }

左只是为了以某种方式摧毁?

3 个答案:

答案 0 :(得分:2)

有两种策略可以解决此问题。总的来说,这是一个状态管理问题:多个组件正在一个联合状态下工作。

选项1:父组件管理状态

这可能是最简单的解决方案。

  • 包含所有其他组件的父组件具有选定产品的列表。
  • 允许用户选择产品的子组件具有@Output()EventEmitter,该事件在用户选择产品时发出。父组件侦听该输出,并将发出的产品添加到其产品列表中。
  • 用于显示选定产品的子组件具有一个@Input()产品数组,基于它们显示产品。父组件将此输入设置为其产品列表。

选择2:国家服务

实施迅速,但关注点比#1更清晰。

  • 实施@Injectable StateService。它具有a)​​一个带有产品列表的BehaviorSubject<Product[]>,b)一种方法addProduct(product: Product),该方法将一个产品添加到BehaviorSubject的当前值并发出。
  • 每个组件都使用该服务(constructor(stateService: StateService))。用户选择产品时,组件将调用this.stateService.addProduct(product)
  • 显示产品的组件会监听服务的产品列表:this.stateService.products.subscribe(products => this.products = products)中的更改,并相应地显示产品。

选项3:使用状态存储库

使用诸如NGRX或Redux之类的东西来为您管理状态。

答案 1 :(得分:0)

您可以将productsSelected数组添加到ProductsComponent,选择时将所选产品推送到其中,然后将其作为输入传递给ReceiptItemComponent(或ReceiptItemsComponent)。不要忘了[()]-香蕉盒,两种方式的数据绑定-如果您要更改子组件中的数量,但要将该数组保存在父组件中。

您还可以使用服务,该服务将selectedProducts保留为behaviorSubject并将其注入两个组件中。然后,您必须订阅两个组件中的更改才能接收更新。

答案 2 :(得分:0)

这正是我写我的库RxCache的目的。它为Angular应用程序提供了推送数据流,而不必增加添加NGRX之类的存储所涉及的复杂性和繁琐的样板代码。

https://github.com/adriandavidbrand/ngx-rxcache

在StackBlitz上进行测试-https://stackblitz.com/edit/angular-3yqpfe

可以在StackBlitz上看到官方的ngrx示例应用程序的重做-https://stackblitz.com/edit/github-tsrf1f