Angular parent 和 child 组件之间的通信
Angular communication between parent and child components
我有一个案例,我有一个 parent 组件和 2 个 child 组件(selection 组件基于 ng-select)
这个想法是,当我 select 和第一个 ng-select 中的项目时,应该在第二个中禁用相同的项目。反之亦然。
在parent中我使用@ViewChildren查询组件和设置禁用输入属性
在 children 中,当我在 ng-select
中选择和项目时,我在 parent 中发出我需要的信息
在这种方法中,我找到了正确的 child 组件并设置了禁用的输入 属性
const connectionSelector = this.connectionSelectors.find(connectionSelector => connectionSelector.source == false);
connectionSelector.disabledConnection = this.selectedSourceConnection;
在 child 组件中,我有 ngOnChanges 方法来检查更改,但 disabledConnection 属性 没有更新
它只在我加载页面时有效
我都在 OnInit 上发出对 parent 的更改,当我更改 ng-select 中的项目时,这些更改被发送到 parent
Parent 视图:
<sc-connection-selector [default]="false" [source]="true" [quick]="false"
[selectedConnection]="selectedSourceConnection"
[disabledConnectionId]="disabledTargetConnectionId"
(dataToEmit)="onValueChanged($event)">
</sc-connection-selector>
Child:
<ng-select [items]="connections" bindLabel="userName"
[placeholder]="'general.select-placeholder' | translate "
(change)="onConnectionChange()"
groupBy="type"
dropdownPosition="bottom"
[(ngModel)]="selectedConnection">
<ng-template ng-optgroup-tmp let-item="item">
<b>{{item.type || 'Unnamed group'}}</b>
</ng-template>
</ng-select>
我在这里错过了什么?
-贾尼
编辑:
您正在更新子组件上的值,而不是父组件上的值,如果
将触发 OnChanges
data-bound property of a directive changes
也就是说,当父组件上的值改变时,会触发子组件上的OnChanges。
为了获得所需的行为,您应该将相关部分(您更新禁用 属性 的部分)从 OnChanges 函数移动到 disabledConnectionId 的 setter,因此每次 ( disabledConnectionId) 改变,你更新下拉,这里是相关代码:
private currentDisabledConnectionId: Number;
@Input()
set disabledConnectionId(val: number) {
if (this.currentDisabledConnectionId !== val) {
this.currentDisabledConnectionId = val;
this.setDisabledFields();
}
}
private setDisabledFields() {
this.connections.find(
connection => connection.id == this.currentDisabledConnectionId
).disabled = true;
console.log("connections: ", this.connections);
}
请注意,我已将输入更改为 setter,并将 属性 保存为私有字段。
另请注意,您在 stackblitz 上发布的内容不会删除以前禁用的字段,只会添加新字段(我怀疑这是因为您只粘贴了一个可重现的示例)。
这是 stackBlitz
上的工作分叉示例
我有一个案例,我有一个 parent 组件和 2 个 child 组件(selection 组件基于 ng-select) 这个想法是,当我 select 和第一个 ng-select 中的项目时,应该在第二个中禁用相同的项目。反之亦然。
在parent中我使用@ViewChildren查询组件和设置禁用输入属性
在 children 中,当我在 ng-select
中选择和项目时,我在 parent 中发出我需要的信息在这种方法中,我找到了正确的 child 组件并设置了禁用的输入 属性
const connectionSelector = this.connectionSelectors.find(connectionSelector => connectionSelector.source == false);
connectionSelector.disabledConnection = this.selectedSourceConnection;
在 child 组件中,我有 ngOnChanges 方法来检查更改,但 disabledConnection 属性 没有更新
它只在我加载页面时有效 我都在 OnInit 上发出对 parent 的更改,当我更改 ng-select 中的项目时,这些更改被发送到 parent
Parent 视图:
<sc-connection-selector [default]="false" [source]="true" [quick]="false"
[selectedConnection]="selectedSourceConnection"
[disabledConnectionId]="disabledTargetConnectionId"
(dataToEmit)="onValueChanged($event)">
</sc-connection-selector>
Child:
<ng-select [items]="connections" bindLabel="userName"
[placeholder]="'general.select-placeholder' | translate "
(change)="onConnectionChange()"
groupBy="type"
dropdownPosition="bottom"
[(ngModel)]="selectedConnection">
<ng-template ng-optgroup-tmp let-item="item">
<b>{{item.type || 'Unnamed group'}}</b>
</ng-template>
</ng-select>
我在这里错过了什么?
-贾尼
编辑:
您正在更新子组件上的值,而不是父组件上的值,如果
将触发 OnChangesdata-bound property of a directive changes
也就是说,当父组件上的值改变时,会触发子组件上的OnChanges。
为了获得所需的行为,您应该将相关部分(您更新禁用 属性 的部分)从 OnChanges 函数移动到 disabledConnectionId 的 setter,因此每次 ( disabledConnectionId) 改变,你更新下拉,这里是相关代码:
private currentDisabledConnectionId: Number;
@Input()
set disabledConnectionId(val: number) {
if (this.currentDisabledConnectionId !== val) {
this.currentDisabledConnectionId = val;
this.setDisabledFields();
}
}
private setDisabledFields() {
this.connections.find(
connection => connection.id == this.currentDisabledConnectionId
).disabled = true;
console.log("connections: ", this.connections);
}
请注意,我已将输入更改为 setter,并将 属性 保存为私有字段。
另请注意,您在 stackblitz 上发布的内容不会删除以前禁用的字段,只会添加新字段(我怀疑这是因为您只粘贴了一个可重现的示例)。
这是 stackBlitz
上的工作分叉示例