在这种情况下,如何正确地将值从二级子组件传递给父组件?
How can I correctly pass a value from a second level sub component to the parent component in this situation?
我不太喜欢 Angular 和 TypeScript(我来自 Java),我有以下问题需要解决。不知道我觉得用的方案对不对,或者有没有更好的方案。
基本上我有一个名为 order-manager.component 的组件,它是呈现此 tables:
的父组件
此父组件包含表示单行的对象列表:
orders: any[];
并进入 ngOnInit() 使用服务检索列表。
正如您在前面的打印屏幕中看到的那样,我的 table 的每一行都可以展开,以便 show\edit 特定对象的详细信息。
为此,我使用了一个名为 order-details 的子组件。所以基本上在我的父组件中 HTML 我有这样的东西:
纹章鱼
此 order-details 子组件本身有 2 个子组件:一个用于 查看模式 ,第二个用于 编辑模式(在上一个屏幕截图中突出显示)。
所以基本上进入我的这个 order-details 组件的代码我只是有:
<p-selectButton [options]="editOrderOption"
[(ngModel)]="editOrderSelectedOption"
(onChange)="editOrderOptionOnChange($event, orderDetail.id)"></p-selectButton>
<div *ngIf="editOrderSelectedOption=='view';then view_content else edit_content">here is ignored</div>
<ng-template #view_content>
<app-view-order [orderDetail]="orderDetail"></app-view-order>
</ng-template>
<ng-template #edit_content>
<app-update-order [orderDetail]="orderDetail"></app-update-order>
</ng-template>
基本上,用户通过 select 按钮选择查看或编辑模式,然后在页面中呈现一个子组件。
在特定情况下,我们使用此 更新顺序 组件进入 编辑模式。
如您在上图中所见,此 update-order 组件允许用户编辑表单,最后它包含 Delete 按钮。单击此按钮我想从我的 table.
中删除表示此订单的对象(table 的这一行)
这是我的问题。表示 table 行的对象列表定义在第一个 order-manager.component 父组件中,按钮定义到第二级 update-order 子组件,这是层次结构:
order-manager component
|
|
|---------> order-details component
|
|
|----------------> update-order component
为了解决这个问题,我想我可以这样做:
用户单击定义到 update-order 子组件中的 Delete 按钮。这是由一个方法处理的,该方法发出一个包含当前行 ID 的事件(它是对象字段的唯一值。
进入order-manager父组件我监听这个事件。收到事件后,它会从 orders 列表中删除,表示我的 table.
的行列表
您认为这是完成此任务的一个相当不错且巧妙的解决方案,还是我遗漏了什么并且有更好的解决方案?
发出值即可。
一个更简单的解决方案是创建一个可以跟踪用户操作的服务。
创建一个服务说 OrderChangeService
并将其注入 order-manager component
和 update-order component
export class OrderChangeService {
deleteIdSubject$ = new Subject<number>(); // import { Subject } from rxjs
deleteIdAction$ = deleteIdSubject$.asObservable()
}
现在 update-order component
当用户点击删除特定订单时,您将调用该主题的 next() 函数
deleteOrder(id: number) {
deleteIdSubject$.next(id);
}
在您的订单管理器组件中,您现在可以在 ngOnInit()
函数中订阅 deleteIdAction$
deleteIdAction$ = this.orderChangeService.deleteIdAction$ // make sure you inject service in the constructor
ngOnInit() {
this.deleteIdAction$.subscribe({
next: (id) => {
// Do Delete action for item with id
}
})
}
基本思想是服务可用于将信息从一个组件传递到另一个组件。随着嵌套组件的深度增加,发射值可能会出现问题
最好的方法实际上是使用 NgRx
进行状态管理。可能有点难用,但效果更好。你可以看看 official documentation of NgRx
首先,您应该在子组件中创建一个输出 属性。
@Output()
updated = new EventEmitter<boolean>();
saveButtonClicked() {
//do update
this.updated.emit(true); //update success
}
在您的 html 中定义它:
<ng-template #edit_content>
<app-update-order [orderDetail]="orderDetail" (updated)="orderUpdated($event)"></app-update-order>
</ng-template>
现在,您可以在父组件中监听更新事件。
orderUpdated(updated:boolean){
if(updated){
}
}
您可以找到有关组件交互的更多信息here
相反,您可以创建一个数据服务,通过它更新和获取数据
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
@Injectable()
export class MessageService {
private siblingMsg = new Subject<string>();
constructor() { }
/*
* @return {Observable<string>} : siblingMsg
*/
public getMessage(): Observable<string> {
return this.siblingMsg.asObservable();
}
/*
* @param {string} message : siblingMsg
*/
public updateMessage(message: string): void {
this.siblingMsg.next(message);
}
}
并且在组件中,您可以使用 subscribe
设置值
import { Component, OnInit, OnDestroy } from '@angular/core';
import { MessageService } from './message.service';
...
export class AppComponent implements OnInit{
public messageForSibling: string;
public subscription: Subscription;
constructor(
private msgservice: MessageService // inject service
) {}
public ngOnDestroy(): void {
this.subscription.unsubscribe(); // onDestroy cancels the subscribe request
}
public ngOnInit(): void {
// set subscribe to message service
this.subscription = this.messageService.getMessage().subscribe(msg => this.messageForSibling = msg);
}
}
我不太喜欢 Angular 和 TypeScript(我来自 Java),我有以下问题需要解决。不知道我觉得用的方案对不对,或者有没有更好的方案。
基本上我有一个名为 order-manager.component 的组件,它是呈现此 tables:
的父组件此父组件包含表示单行的对象列表:
orders: any[];
并进入 ngOnInit() 使用服务检索列表。
正如您在前面的打印屏幕中看到的那样,我的 table 的每一行都可以展开,以便 show\edit 特定对象的详细信息。
为此,我使用了一个名为 order-details 的子组件。所以基本上在我的父组件中 HTML 我有这样的东西:
纹章鱼此 order-details 子组件本身有 2 个子组件:一个用于 查看模式 ,第二个用于 编辑模式(在上一个屏幕截图中突出显示)。
所以基本上进入我的这个 order-details 组件的代码我只是有:
<p-selectButton [options]="editOrderOption"
[(ngModel)]="editOrderSelectedOption"
(onChange)="editOrderOptionOnChange($event, orderDetail.id)"></p-selectButton>
<div *ngIf="editOrderSelectedOption=='view';then view_content else edit_content">here is ignored</div>
<ng-template #view_content>
<app-view-order [orderDetail]="orderDetail"></app-view-order>
</ng-template>
<ng-template #edit_content>
<app-update-order [orderDetail]="orderDetail"></app-update-order>
</ng-template>
基本上,用户通过 select 按钮选择查看或编辑模式,然后在页面中呈现一个子组件。
在特定情况下,我们使用此 更新顺序 组件进入 编辑模式。
如您在上图中所见,此 update-order 组件允许用户编辑表单,最后它包含 Delete 按钮。单击此按钮我想从我的 table.
中删除表示此订单的对象(table 的这一行)这是我的问题。表示 table 行的对象列表定义在第一个 order-manager.component 父组件中,按钮定义到第二级 update-order 子组件,这是层次结构:
order-manager component
|
|
|---------> order-details component
|
|
|----------------> update-order component
为了解决这个问题,我想我可以这样做:
用户单击定义到 update-order 子组件中的 Delete 按钮。这是由一个方法处理的,该方法发出一个包含当前行 ID 的事件(它是对象字段的唯一值。
进入order-manager父组件我监听这个事件。收到事件后,它会从 orders 列表中删除,表示我的 table.
的行列表
您认为这是完成此任务的一个相当不错且巧妙的解决方案,还是我遗漏了什么并且有更好的解决方案?
发出值即可。
一个更简单的解决方案是创建一个可以跟踪用户操作的服务。
创建一个服务说 OrderChangeService
并将其注入 order-manager component
和 update-order component
export class OrderChangeService {
deleteIdSubject$ = new Subject<number>(); // import { Subject } from rxjs
deleteIdAction$ = deleteIdSubject$.asObservable()
}
现在 update-order component
当用户点击删除特定订单时,您将调用该主题的 next() 函数
deleteOrder(id: number) {
deleteIdSubject$.next(id);
}
在您的订单管理器组件中,您现在可以在 ngOnInit()
函数中订阅 deleteIdAction$
deleteIdAction$ = this.orderChangeService.deleteIdAction$ // make sure you inject service in the constructor
ngOnInit() {
this.deleteIdAction$.subscribe({
next: (id) => {
// Do Delete action for item with id
}
})
}
基本思想是服务可用于将信息从一个组件传递到另一个组件。随着嵌套组件的深度增加,发射值可能会出现问题
最好的方法实际上是使用 NgRx
进行状态管理。可能有点难用,但效果更好。你可以看看 official documentation of NgRx
首先,您应该在子组件中创建一个输出 属性。
@Output()
updated = new EventEmitter<boolean>();
saveButtonClicked() {
//do update
this.updated.emit(true); //update success
}
在您的 html 中定义它:
<ng-template #edit_content>
<app-update-order [orderDetail]="orderDetail" (updated)="orderUpdated($event)"></app-update-order>
</ng-template>
现在,您可以在父组件中监听更新事件。
orderUpdated(updated:boolean){
if(updated){
}
}
您可以找到有关组件交互的更多信息here
相反,您可以创建一个数据服务,通过它更新和获取数据
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
@Injectable()
export class MessageService {
private siblingMsg = new Subject<string>();
constructor() { }
/*
* @return {Observable<string>} : siblingMsg
*/
public getMessage(): Observable<string> {
return this.siblingMsg.asObservable();
}
/*
* @param {string} message : siblingMsg
*/
public updateMessage(message: string): void {
this.siblingMsg.next(message);
}
}
并且在组件中,您可以使用 subscribe
设置值import { Component, OnInit, OnDestroy } from '@angular/core';
import { MessageService } from './message.service';
...
export class AppComponent implements OnInit{
public messageForSibling: string;
public subscription: Subscription;
constructor(
private msgservice: MessageService // inject service
) {}
public ngOnDestroy(): void {
this.subscription.unsubscribe(); // onDestroy cancels the subscribe request
}
public ngOnInit(): void {
// set subscribe to message service
this.subscription = this.messageService.getMessage().subscribe(msg => this.messageForSibling = msg);
}
}