我有一个页面可以创建一个Kendo窗口,其中有一个Multiselect作为窗口的一部分。
<div class="col-sm-9" data-bind="loadingWhen: isLoading.Participants">
<select id="cmboParticipants" multiple="multiple" data-bind="loadingWhen: isLoading.Participants, multiselect: MultiSelectOptions, selectedOptions: Participants, valueUpdate: 'keyup'"></select>
</div>
用于填充列表的代码绑定如下:
self.ParticipantsList.subscribe(function (val) {
if (!val || !val.Other) {
//clear the list
$("select#cmboParticipants").empty();
$("select#cmboParticipants").multiselect('rebuild');
var empOptGroup = $("<optgroup label='Other' />");
$("select#cmboParticipants").append(otherOptGroup);
var rteOptGroup = $("<optgroup label='Other2' />");
$("select#cmboParticipants").append(other2OptGroup);
$("select#cmboParticipants").multiselect('rebuild');
return;
}
var selected = self.Participants();
$("select#cmboParticipants").empty();
$("select#cmboParticipants").multiselect('rebuild');
if (val.Other.length > 0) {
var otherOptGroup = $("<optgroup label='Other' />");
$.each(val.Other, function (key, obj) {
$(otherOptGroup).append($("<option>", {
text: obj.Text,
value: obj.Value
}));
});
$("select#cmboParticipants").append(otherOptGroup);
}
if (val.Other2.length > 0) {
var other2OptGroup = $("<optgroup label='Other2' />");
$.each(val.Other2, function (key, obj) {
$(other2OptGroup).append($("<option>", {
text: obj.Text,
value: obj.Value
}));
});
$("select#cmboParticipants").append(other2OptGroup);
}
$("select#cmboParticipants").val(selected)
$("select#cmboParticipants").multiselect('rebuild');
});
当我从多选中取消选中一个项目时,我注意到在knockout-3.0.0的trackChanges代码中,当前内容中项目的顺序与先前内容的顺序不同。具体如下代码:
// Each time the array changes value, capture a clone so that on the next
// change it's possible to produce a diff
var previousContents = [].concat(target.peek() || []);
cachedDiff = null;
target.subscribe(function(currentContents) {
// Make a copy of the current contents and ensure it's an array
currentContents = [].concat(currentContents || []);
// Compute the diff and issue notifications, but only if someone is listening
if (target.hasSubscriptionsForEvent(arrayChangeEventName)) {
var changes = getChanges(previousContents, currentContents);
if (changes.length) {
target['notifySubscribers'](changes, arrayChangeEventName);
}
}
// Eliminate references to the old, removed items, so they can be GCed
previousContents = currentContents;
cachedDiff = null;
pendingNotifications = 0;
});
由于订单不同,我认为这会导致项目在不应该被删除时被标记为删除。
例如,我从多选中移除项目e56,如下面的两个数组所示(注意由于某种原因它们的顺序不同)
原始阵列:
0: "g3"
1: "e36"
2: "e46"
3: "e56"
4: "e55"
5: "e62"
6: "e58"
7: "e53"
8: "e59"
9: "e57"
10: "e60"
11: "e61"
12: "e54"
length: 13
修改后的数组:
0: "e36"
1: "e46"
2: "e55"
3: "e62"
4: "e58"
5: "e53"
6: "e59"
7: "e57"
8: "e60"
9: "e61"
10: "e54"
11: "g3"
length: 12
出于某种原因,我在多选中删除的项目(e56)下方的所有内容现已标记为&#34;已删除&#34;通过getChanges调用。这导致取消选择所有这些项目。
我知道我们在使用以下代码加载viewModel期间从Ajax检索数据时对列表进行排序:
loadParticipantsList(0, function () {
var lst = [];
$.each(model.lstOther2, function (index, item) {
lst.push('g' + item.value);
});
$.each(model.lstOther, function (index, item) {
lst.push('e' + item.value);
});
self.Participants(lst);
});
我想如果我在将它传递给trackChanges之前对其进行排序,它就不会将事物标记为已删除。我如何抓住这些项目并在它们到达那一点之前对它们进行排序?