You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular9中EventEmitter无法正常emit携带KeyValuePair数组属性的对象

问题根因

该问题的核心是数组为引用类型,你 emit 的对象中 predefinedParameters 传递的是原数组的引用,若有其他订阅者(比如绑定了该 Output 事件的父组件)在处理逻辑中修改了这个数组,会导致所有拿到该引用的地方都感知到变更。你看到的控制台打印结果异常,是因为浏览器控制台打印对象为懒加载模式,点开查看属性时读取的是修改后的最新值,所以显示数组为空。

解决方案

1. emit 时传入数组拷贝,切断引用关联

因为你的 KeyValuePair 是简单值类型,做浅拷贝即可解决引用互相影响的问题,同时建议你主动使用定义好的 SelectedApiCall 构造函数创建实例,避免字面量隐式类型转换的潜在问题:

// 原字面量创建逻辑
// let selectedApiCall = {
//     identifier: identifier,
//     predefinedParameters: parametersKeyValuePair
// }

// 修改为构造函数创建+数组浅拷贝
const selectedApiCall = new SelectedApiCall(
    identifier,
    [...parametersKeyValuePair] // 展开运算符做浅拷贝,也可替换为 parametersKeyValuePair.slice()
);

2. 移除不合理的内部订阅

@Output 装饰的 EventEmitter 设计用途是给父组件监听事件,不建议在组件内部订阅。如果你需要在 emit 后执行内部逻辑,直接把逻辑写到 emit 语句之后即可,避免多播逻辑混乱。

3. 可选:检查父组件事件处理逻辑

如果父组件的事件处理函数中确实有清空/修改 predefinedParameters 数组的操作,要么调整父组件逻辑使用拷贝后的数据修改,要么保持 emit 时传拷贝的做法,避免相互影响。

修改后的完整代码示例

apiCall: IApiCallHistory | undefined;
@Output() selectedApiCallChange = new EventEmitter<SelectedApiCall>();

getApiCall(identifier: string) {
    const parametersKeyValuePair = new Array<KeyValuePair<string, string>>();
    
    this.sapEtService.getApiCallHistoryById(identifier)
        .subscribe(apiCall => {
            this.apiCall = apiCall;
            for (let parameter of this.apiCall.apiCallWithParameters.apiCallParameters) {
                parametersKeyValuePair.push(
                    new KeyValuePair<string, string>(
                        parameter.identifier,
                        parameter.value
                    ));
            }
            // 用构造函数创建实例 + 数组浅拷贝
            const selectedApiCall = new SelectedApiCall(
                identifier,
                [...parametersKeyValuePair]
            );

            console.log('parametersKeyValuePair:::: ', parametersKeyValuePair);
            console.log('selectedApiCall.predefinedParameters:::: ', selectedApiCall.predefinedParameters);

            this.selectedApiCallChange.emit(selectedApiCall);
            // 原内部订阅的逻辑直接放在这里执行即可,不需要额外订阅
            console.log('this.selectedApiCallChange in ApiCall History:::: ', selectedApiCall);
        });
}

内容的提问来源于stack exchange,提问作者Reza Gholizadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:30:01