我正在研究有关产品的简单应用程序,基本上当用户选择产品时,它应该发送到另一个可以容纳产品的组件。
产品是一一选择的,我从不发送清单!只有逐项!
所以基本上当我点击屏幕中间的任何产品(产品食品 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
装饰器以及services
进行了红色,我想@input和@output是正确的解决方案,因为我正在一个接一个地发送项目?
但是我不知道如何解决这个问题。
任何形式的帮助都会很棒
谢谢
FJC帮助后:
<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>
正如你所看到的,伙计们:
1.(我添加了addReceiptItem
方法
2.( 此方法接受点击的产品:
addReceiptItem(receiptItem: Product) {
this._sharedService.addReceiptItem(receiptItem);
}
3.(注入服务'_sharedService
'并在那里创建方法,也称为 'addReceiptItem'
4.(在我的服务中,我创建了这样的BehaviorSubject
:private receiptItem = new BehaviorSubject<any>(undefined);
4.(服务中的方法如下所示:
addReceiptItem(receiptItems: Product) {
this.arr1.push(receiptItems);
this.receiptItem.next(this.arr1);
}
此方法将单击的项目推送到一个数组,该数组将发送到显示产品的组件
4.11(还添加了获取返回行为主题的数据的方法:
getReceiptItem(): BehaviorSubject<any> {
return this.receiptItem;
}
5.(编辑了显示产品的组件(代码也在做任何事情之前发布 - 空打字稿文件(,现在看起来像这样:
export class ReceiptItemComponent implements OnInit {
constructor(private _sharedService: SharedService) { }
receiptItems: Product[];
ngOnInit() {
this._sharedService.getReceiptItem().subscribe(products => this.receiptItems = products);
}
}
左边只是以某种方式破坏?
有几种策略可以解决这个问题。总的来说,这是一个状态管理问题:多个组件正在处理一个联合状态。
选项 1:父组件管理状态
这可能是最简单的解决方案。
- 包含所有其他组件的父组件具有所选产品的列表。
- 允许用户选取产品的子组件具有在用户选取产品时发出的 @Output(( EventEmitter。父组件侦听该输出,并将发出的产品添加到其产品列表中。
- 显示选定产品的子组件具有 @Input(( 产品数组,它们基于该数组显示产品。父组件将此输入设置到其产品列表中。
选项2:国家服务
快速实施,但比#1更干净。
- 实现@Injectable
StateService
.它具有 a( 带有产品列表的BehaviorSubject<Product[]>
,b( 将产品添加到BehaviorSubject
的当前值并发出它的方法addProduct(product: Product)
。 - 每个组件都使用该服务 (
constructor(stateService: StateService)
(。当用户选取产品时,组件将调用this.stateService.addProduct(product)
。 - 显示产品的组件侦听服务产品列表中的更改:相应地
this.stateService.products.subscribe(products => this.products = products)
和显示产品。
选项 3:使用状态存储库
使用像 NGRX 或 Redux 这样的东西来为你处理状态管理。
您可以将 productSelected 数组添加到 ProductsComponent,在选择时将所选产品推送到该数组中,然后将其作为输入传递给 ReceiptItemComponent(或 ReceiptItemsComponent(。不要忘记 [((] -- 香蕉盒,双向数据绑定 - 如果您要更改子组件中的数量,但要将数组保存在父组件中。
您也可以使用一个服务,该服务将选定的产品保存为行为主体并将其注入到两个组件中。然后,您必须订阅两个组件中的更改才能接收更新。
这正是我编写库 RxCache 的目的。它为 Angular 应用程序提供推送数据流,而不必增加添加像 NGRX 这样的存储所涉及的复杂性和荒谬的样板代码量。
https://github.com/adriandavidbrand/ngx-rxcache
StackBlitz 上的测试平台 - https://stackblitz.com/edit/angular-3yqpfe
官方 ngrx 示例应用程序的重做可以在 StackBlitz 上看到 - https://stackblitz.com/edit/github-tsrf1f