如何合并两个循环实现对象值重叠?Angular通道映射与复选框禁用问题
搞定通道映射与循环合并的两个问题
一、先解决「domain值为N时禁用对应user复选框」的问题
首先得明确:咱们是靠通道名称来对应两个数组里的项,对吧?那第一步先把domainChannels转成一个键值对的映射表,这样后面找状态的时候能直接拿,不用每次都循环查找。
在组件里加这段代码:
// 把domain通道转成{通道名: 状态值}的映射,方便快速查找 domainChannelStatus = this.domainChannels.reduce((statusMap, channel) => { statusMap[channel.channelName] = channel.channelValue; return statusMap; }, {} as Record<string, string>);
然后在模板里渲染userChannels的时候,直接用这个映射表判断是否禁用:
<div *ngFor="let userChan of userChannels"> <label> <input type="checkbox" <!-- 当对应domain状态是"N"时禁用 --> [disabled]="domainChannelStatus[userChan.channelName] === 'N'" [(ngModel)]="userChan.selected" > {{ userChan.channelName }} </label> </div>
要是你的两个数组是严格按顺序对应的(比如第1个user通道对应第1个domain通道),那也可以直接用索引取,不用转映射:
<div *ngFor="let userChan of userChannels; let i = index"> <label> <input type="checkbox" [disabled]="domainChannels[i]?.channelValue === 'N'" [(ngModel)]="userChan.selected" > {{ userChan.channelName }} </label> </div>
不过还是按名称映射更靠谱,毕竟数组顺序万一变了就出问题。
二、合并两个循环,实现对象值重叠
其实就是把两个数组里的对应通道整合成一个新对象数组,这样渲染的时候只循环一次就行。咱们可以用map结合find来做,或者先转成Map提升性能。
方式1:基础版(适合数据量小的情况)
在组件里合并数组:
// 合并user和domain的通道数据,把domain的状态整合进来 combinedChannels = this.userChannels.map(userChan => { // 找到对应名称的domain通道 const matchedDomainChan = this.domainChannels.find(domainChan => domainChan.channelName === userChan.channelName); return { // 把user通道的所有属性拷过来 ...userChan, // 加上domain的状态,找不到的话默认设为"Y"(你可以改默认值) domainStatus: matchedDomainChan?.channelValue || 'Y' }; });
然后模板里只循环这个合并后的数组:
<div *ngFor="let chan of combinedChannels"> <label> <input type="checkbox" [disabled]="chan.domainStatus === 'N'" [(ngModel)]="chan.selected" > {{ chan.channelName }} </label> </div>
方式2:性能优化版(适合数据量大的情况)
如果通道数量很多,find每次循环都要遍历数组,效率有点低。咱们可以先把domainChannels转成Map,这样查找是O(1)的:
// 先把domain通道转成Map,键是通道名,值是状态 const domainStatusMap = new Map(this.domainChannels.map(domainChan => [domainChan.channelName, domainChan.channelValue])); // 再合并数组 combinedChannels = this.userChannels.map(userChan => ({ ...userChan, domainStatus: domainStatusMap.get(userChan.channelName) || 'Y' }));
模板和上面一样,这样合并的速度会快很多。
内容的提问来源于stack exchange,提问作者Nehal Jaisalmeria
相关产品推荐
相关产品推荐

