数组元素移除异常及双向选框数据迁移功能实现求助
Fixing Two-Way Multi-Select Migration & Array Sync Issues
Let's walk through what's causing your problems and fix them properly:
The Root Causes
- DOM Sync Failure: When you move elements between selects, you're only cloning them to the target box but never removing them from the original one. That's why deleted items seem to "come back"—they were still in the original select all along.
- Array Sync Failure: You're only pushing new items to the target array, but never removing them from the source array. This mismatch between your DOM state and data arrays leads to inconsistent behavior.
- Incorrect Array Removal: Your
removeItemfunction usesfilter, which returns a new array—but you never assign this new array back to your originalcolData(orfirmData/data). So the original array remains unchanged.
Corrected Code Implementation
First, let's fix the button click handlers to handle multi-select cases (since your selects are multiple="multiple") and keep both DOM and arrays in sync:
Right Button (Move from lstBox1 to lstBox2)
"click #btnRight": function(e){ const self = this; // Get all selected options (handle multiple selections) const selectedOpts = $('#lstBox1 option:selected'); selectedOpts.each(function() { const optionText = $(this).text(); // Clone to target select and remove from original $('#lstBox2').append($(this).clone()); $(this).remove(); // Remove from source array (firmData) self.firmData = self.firmData.filter(item => item.DisplayName !== optionText); // Add to target array (data) self.data.push({columnsexpo: optionText}); }); }
Left Button (Move from lstBox2 to lstBox1)
"click #btnLeft": function(e){ const self = this; const selectedOpts = $('#lstBox2 option:selected'); selectedOpts.each(function() { const optionText = $(this).text(); // Clone to target select and remove from original $('#lstBox1').append($(this).clone()); $(this).remove(); // Remove from source array (data) self.data = self.data.filter(item => item.columnsexpo !== optionText); // Add to target array (firmData) self.firmData.push({DisplayName: optionText}); }); }
Key Improvements Explained
- Handle Multiple Selections: Using
each()onselectedOptsensures we process every selected item, not just the first one. - DOM Sync: After cloning to the target select, we call
$(this).remove()to delete the option from the original select—no more "ghost" items coming back. - Array Sync: We use
filter()to create a new array excluding the moved item, then assign it back to the original array (e.g.,self.firmData = ...). This properly updates the source array instead of leaving it unchanged. - Consistent Data Structure: When pushing to the target array, we match the object structure your initial render code uses (e.g.,
{DisplayName: optionText}forfirmData).
Bonus: Initial Render Best Practice
To make sure your initial select options match your arrays perfectly, you can clear the selects before re-rendering (if you ever need to refresh them):
// For lstBox1 $("#lstBox1").empty(); self.firmData.forEach(function (data) { $("#lstBox1").append($('<option class="items">').text(data.DisplayName).attr('value', data.DisplayName)); }); // For lstBox2 $("#lstBox2").empty(); self.data.forEach(function (data) { $("#lstBox2").append($('<option class="items">').text(data.columnsexpo).attr('value', data.columnsexpo)); });
This ensures your DOM always reflects the current state of your data arrays, eliminating any inconsistencies.
内容的提问来源于stack exchange,提问作者chethu
相关产品推荐
相关产品推荐

