ExtJS需求:移除父标签时同步删除TagField中的对应子标签
需求说明
现有两个TagField组件:
- 父标签FieldA:包含a、b、c、d、e五个类别,支持多选
- 子标签FieldB:下拉选项根据FieldA的选择,通过调用store服务加载(单选传单个值,多选传逗号分隔值),用户可将对应子标签添加到FieldB中
核心需求:当移除FieldA中的某个父标签时,自动删除FieldB中属于该父标签的已添加子标签。例如:选中父标签a后添加了子标签x、z,移除a时,FieldB中的x、z要被自动移除。
现有组件代码
TagField配置代码
{ fieldLabel: 'FieldA', displayField: 'Label', itemId:'FieldA', valueField: 'Type', listeners:{ change: 'selectedFieldATypes' }, bind: { store: '{FieldATypes}', hidden: '{status === "NULL"}' }, },{ fieldLabel: 'FieldB', itemId:'FieldB', displayField: 'label', valueField: 'name', editable: true, selectOnFocus: false, listeners:{ render: 'FieldATypes' }, bind: { store: '{FieldBStore}', hidden: '{status === "NULL"}' }, }
现有处理函数代码
selectedFieldATypes: function(){ const viewModel = this.getViewModel(); viewModel.set('selectedtypesarray',selectedTypes); selectedTypes=Ext.ComponentQuery.query('#FieldB').getValue(); if(selectedTypes.length==0){ this.getStore('FieldBStore').load({params: {Ids:[Comma seperated ID's of selected Parent tag]}}); } else{ this.getStore('FieldBStore').load({params: {groupIds:All id's if not parent tag is selected}}) } },
实现方案
要搞定移除父标签自动删对应子标签的需求,核心是在父标签变更时,对比前后选中的父标签,找出被删掉的那些,再把FieldB里关联的子标签清掉。具体操作如下:
1. 存储父标签历史选中值
在ViewModel中添加previousFieldAValues字段,用来记录上一次FieldA的选中内容,初始值设为空数组即可。
2. 重写selectedFieldATypes函数
更新原有函数,增加对比父标签变更、清理对应子标签的逻辑:
selectedFieldATypes: function(field, newValue, oldValue) { const viewModel = this.getViewModel(); const fieldB = Ext.ComponentQuery.query('#FieldB')[0]; let currentFieldBValues = fieldB.getValue() || []; // 找出被移除的父标签 const removedParents = oldValue ? oldValue.filter(type => !newValue.includes(type)) : []; if (removedParents.length > 0) { // 需根据实际业务字段调整,假设子标签store中有parentType字段关联父标签的Type值 const fieldBStore = this.getStore('FieldBStore'); removedParents.forEach(removedType => { // 提取所有属于该被删父标签的子标签name const kidsToRemove = fieldBStore.query('parentType', removedType).getRange().map(record => record.get('name')); // 从FieldB已选值中过滤掉这些子标签 currentFieldBValues = currentFieldBValues.filter(name => !kidsToRemove.includes(name)); }); // 更新FieldB的选中状态 fieldB.setValue(currentFieldBValues); } // 更新ViewModel中的选中记录与历史记录 viewModel.set('selectedtypesarray', newValue); viewModel.set('previousFieldAValues', newValue); // 修正原有加载子标签的参数逻辑 if (newValue.length > 0) { // 多选时转成逗号分隔的字符串传给后端 const ids = newValue.join(','); this.getStore('FieldBStore').load({params: {Ids: ids}}); } else { // 未选父标签时加载所有子标签 this.getStore('FieldBStore').load({params: {groupIds: 'all'}}); } },
3. 确认监听配置
FieldA的change监听无需额外修改,ExtJS默认会将field、newValue、oldValue三个参数传入回调函数,刚好满足我们的需求。
关键注意点
- 子标签的store记录中必须包含关联父标签的字段(如示例中的
parentType),如果后端接口未返回该字段,需要协调后端补充,否则无法判断子标签所属的父标签。 - 代码中的字段名(如
parentType、name)需要与实际业务使用的字段保持一致,不要直接照搬示例。
内容的提问来源于stack exchange,提问作者Aakash Singh
相关产品推荐
相关产品推荐

