什么是更好的方法以及如何实现将对象从一个嵌套组件发送到另一个
What is a better way and how to achieve sending object from one nested component to another
我正在开发关于产品的简单应用程序,基本上当用户选择产品时,它应该被发送到另一个可以保存产品的组件。
产品总是一一选择,我从不发送列表!仅 一项一项 !
所以基本上当我点击屏幕中间的任何产品时(Product food 1, Product food 2, Product food 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;
}
}
现在我将 post 我应该接收产品的正确组件 :
<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() {
}
}
所以这个 'right' 组件应该从中间接收点击的产品,我不知道该怎么做,我红了 @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) 还添加了获取数据的方法 returns BehaviorSubject:
getReceiptItem(): BehaviorSubject<any> {
return this.receiptItem;
}
5.) 编辑显示产品的组件(代码在执行任何操作之前也被 post 编辑 - 空打字稿文件),现在它看起来像这样:
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
。它有一个 BehaviorSubject<Product[]>
和一个产品列表,b) 一个方法 addProduct(product: Product)
将产品添加到 BehaviorSubject
的当前值并发出它。
- 每个组件都使用该服务 (
constructor(stateService: StateService)
)。当用户选择产品时,组件调用 this.stateService.addProduct(product)
。
- 显示产品的组件侦听服务产品列表中的更改:
this.stateService.products.subscribe(products => this.products = products)
并相应地显示产品。
选项 3:使用 State Store 图书馆
使用 NGRX 或 Redux 之类的工具来为您管理状态。
您可以将 productsSelected 数组添加到您的 ProductsComponent,您可以在选择时将所选产品推送到其中,然后将其作为输入传递给您的 ReceiptItemComponent(或 ReceiptItemsComponent)。不要忘记 [()] -- 一盒香蕉,双向数据绑定 - 如果您要更改子组件中的数量但要将数组保存在父组件中。
您也可以使用一项服务,该服务将 selectedProducts 作为 behaviorSubject 保存并将其注入到两个组件中。然后您必须订阅两个组件中的更改才能接收更新。
这正是我编写库 RxCache 的目的。它向 Angular 应用程序提供推送数据流,而无需增加添加像 NGRX 这样的商店所涉及的复杂性和大量样板代码。
https://github.com/adriandavidbrand/ngx-rxcache
StackBlitz 测试台 - https://stackblitz.com/edit/angular-3yqpfe
可以在 StackBlitz 上看到官方 ngrx 示例应用程序的重做 - https://stackblitz.com/edit/github-tsrf1f
我正在开发关于产品的简单应用程序,基本上当用户选择产品时,它应该被发送到另一个可以保存产品的组件。
产品总是一一选择,我从不发送列表!仅 一项一项 !
所以基本上当我点击屏幕中间的任何产品时(Product food 1, Product food 2, Product food 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;
}
}
现在我将 post 我应该接收产品的正确组件 :
<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() {
}
}
所以这个 'right' 组件应该从中间接收点击的产品,我不知道该怎么做,我红了 @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) 还添加了获取数据的方法 returns BehaviorSubject:
getReceiptItem(): BehaviorSubject<any> {
return this.receiptItem;
}
5.) 编辑显示产品的组件(代码在执行任何操作之前也被 post 编辑 - 空打字稿文件),现在它看起来像这样:
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
。它有一个BehaviorSubject<Product[]>
和一个产品列表,b) 一个方法addProduct(product: Product)
将产品添加到BehaviorSubject
的当前值并发出它。 - 每个组件都使用该服务 (
constructor(stateService: StateService)
)。当用户选择产品时,组件调用this.stateService.addProduct(product)
。 - 显示产品的组件侦听服务产品列表中的更改:
this.stateService.products.subscribe(products => this.products = products)
并相应地显示产品。
选项 3:使用 State Store 图书馆
使用 NGRX 或 Redux 之类的工具来为您管理状态。
您可以将 productsSelected 数组添加到您的 ProductsComponent,您可以在选择时将所选产品推送到其中,然后将其作为输入传递给您的 ReceiptItemComponent(或 ReceiptItemsComponent)。不要忘记 [()] -- 一盒香蕉,双向数据绑定 - 如果您要更改子组件中的数量但要将数组保存在父组件中。
您也可以使用一项服务,该服务将 selectedProducts 作为 behaviorSubject 保存并将其注入到两个组件中。然后您必须订阅两个组件中的更改才能接收更新。
这正是我编写库 RxCache 的目的。它向 Angular 应用程序提供推送数据流,而无需增加添加像 NGRX 这样的商店所涉及的复杂性和大量样板代码。
https://github.com/adriandavidbrand/ngx-rxcache
StackBlitz 测试台 - https://stackblitz.com/edit/angular-3yqpfe
可以在 StackBlitz 上看到官方 ngrx 示例应用程序的重做 - https://stackblitz.com/edit/github-tsrf1f