angularjs - 单击下一行中的select2时如何防止select2清除所选值
问题描述
我的网络应用程序使用 angularjs 和 php。在网站中,有一个部分可以添加用户的估算值。它具有 select2 作为下拉列表,用于填充库存中的现有项目。
<tr class="valign-top"
ng-repeat="estimate in workorder.steps[1].estimates track by $index"
ng-init="item_key = $index">
<div id="material_div{{$index}}"
ng-if="estimate.type == 'material'"
class="create_Wo_forms inspec_crt_forms margin-0">
<select
style="width: 100%!important;"
id="parts_selected{{$index}}"
stepIndex="{{estimatesselectedStep}}"
itemIndex="{{$index}}"
class="crt-wo-input inspec-input"
item_wo_create_select>
</select>
</div>
</tr>
整个部分在 HTML 文件中的 ng-repeat 中。
directive('itemWoCreateSelect', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
var stepIndex = attrs.stepindex;
var elemIndex = attrs.itemindex;
var item = scope.workorder.steps[stepIndex]['estimates'][elemIndex];
$(elem).append('<option>' + item['name'] + '</option>');
scope.selected_items = [];
angular.forEach(scope.workorder.steps[stepIndex]['estimates'], function (v) {
if (v['item_id'] && v['item_id'] != null && !(v['item_id'] == item['item_id'] && v['unit_cost'] == item['unit_cost'])) {
scope.selected_items.push({ 'item_id': v['item_id'], 'unit_price': v['unit_cost'] });
}
});
var formatRepo = function (repo) {
if (repo.loading)
return repo.text;
var markup = '<span class="label">';
if (repo.hasOwnProperty('item_name') && repo.item_name.trim()) {
markup += repo.item_name + ' (' + repo.unit_price + ')' + '';
} else {
markup += repo.text + '';
}
markup += '</span>';
return markup;
};
var formatRepoSelection = function (repo) {
if (repo.hasOwnProperty('item_name')) {
return repo.item_name + ' (' + repo.unit_price + ')';
} else {
item['name'] = repo.id;
return repo.id;
}
};
$(elem).select2({
placeholder: "Search for item",
tags: true,
ajax: {
type: 'POST',
url: version5Url + 'inventory/getMasterStocksForInvoice',
tags: true,
data: function (params) {
return {
token: scope.token,
user_id: scope.user_id,
client_id: scope.client_id,
search: params.term,
selected_items: scope.selected_items
};
},
dataType: 'json',
delay: 250,
processResults: function (data, params) {
$(elem).find('option').remove();
if (item['item_id']) {
delete item['item_id'];
}
item['unit_cost'] = 0;
item['applied_taxes'] = [];
item['selected_tax'] = [];
item['amount'] = 0;
item['quantity'] = 0;
item['description'] = '';
scope.details = data.parts;
scope.$apply();
return {
results: data.parts,
pagination: false
};
},
cache: false
},
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 0,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
$(elem).on("select2:select", function () {
var index = parseInt($(elem).val());
console.log("Slect", index)
if (!isNaN(index)) {
angular.forEach(scope.details, function (value, k) {
if (value['id'] == index) {
item['quantity'] = 1;
item['lot_number'] = value.lot_number;
item['item_id'] = value.item_id;
item['name'] = value.item_name + ' (' + value.unit_price + ')';
item['description'] = value.item_description;
item['unit_cost'] = value['unit_price'];
item['applied_taxes'] = [];
item['selected_tax'] = [];
if (value['taxes'] != '' && value['taxes'] != null) {
var tax_array = value['taxes'].split(',').map(function (x) {
return parseInt(x);
});
angular.forEach(scope.newTaxes, function (value, key) {
angular.forEach(tax_array, function (v1, k1) {
if (value['tax_id'] == v1) {
tax_array.splice(k1, 1);
}
});
});
item['applied_taxes'] = tax_array;
angular.forEach(tax_array, function (value) {
var result = scope.taxes.filter(function (obj) {
return obj.tax_id == value;
});
if (result.length > 0) {
item['selected_tax'].push(result[0].tax_name + ' (' + result[0].rate + '%)');
}
});
}
}
});
} else {
if (item['item_id']) {
delete item['item_id'];
}
item['unit_cost'] = 0;
item['applied_taxes'] = [];
item['selected_tax'] = [];
item['amount'] = 0;
item['quantity'] = 0;
item['description'] = '';
}
scope.$apply();
});
}
};
})
select2 由 js 文件中的指令初始化。
所有这些函数都曾在 select2 版本 3.x 中工作。但是我最近将 select2 升级到了 4.0.13 版本,并且估计部分中的 select2 下拉菜单不再正常工作。
ISSUE: 第一行的选择很好。添加新行时,第一行的 select2 下拉列表中的选定值将被清除。
如果需要,请询问更多信息。提前致谢!
解决方案
来自Joe Enzminger 的 Anwser这里的诀窍是将 select2 初始化包装在一个超时函数中,以便选项在 DOM 中作为正常选择下拉列表的一部分可用。只有选项成为 DOM 的一部分后,才能将下拉列表转换为 select2 下拉列表。
第一个 $timeout 是必要的,因为选项在下一个摘要周期之前不会出现在 DOM 中。这样做的问题是,如果您的应用程序稍后更改模型,则不会将新选项添加到控件中。
$timeout(function() {
$(elem).select2({
placeholder: "Search for item",
tags: true,
ajax: {
type: 'POST',
url: version5Url + 'inventory/getMasterStocksForInvoice',
tags: true,
data: function (params) {
return {
token: scope.token,
user_id: scope.user_id,
client_id: scope.client_id,
search: params.term,
selected_items: scope.selected_items
};
},
dataType: 'json',
delay: 250,
processResults: function (data, params) {
$(elem).find('option').remove();
if (item['item_id']) {
delete item['item_id'];
}
item['unit_cost'] = 0;
item['applied_taxes'] = [];
item['selected_tax'] = [];
item['amount'] = 0;
item['quantity'] = 0;
item['description'] = '';
scope.details = data.parts;
scope.$apply();
return {
results: data.parts,
pagination: false
};
},
cache: false
},
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 0,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
});