我正在使用 knockoutjs 与 MVC5 来显示员工的职位列表。根据员工角色列表应该改变。我第一次选择角色时一切正常,但是当我改变角色然后获得
错误
"您不能将多个绑定应用于同一个元素。"
我试图了解这个和解决方案背后的原因,然后得到一个我们需要使用ko.cleanNode(document.getElementById(" abc"))的解决方案;但它没有用。
代码
var initialData = [{
availableItems: data.availableItems
}, {
selectedItems: data.selectedItems
}];
function Item(titleText, userId, isSelected) {
this.title = ko.observable(titleText);
this.isSelected = ko.observable(isSelected);
this.userId = ko.observable(userId);
}
var SelectableItemViewModel = function(items) {
var self = this;
self.filter = ko.observable("");
self.availableItems = ko.observableArray(ko.utils.arrayMap(items[0].availableItems, function(item) {
return new Item(item.UserName, item.UserId, item.Status);
}));
self.selectedItems = ko.observableArray(ko.utils.arrayMap(items[1].selectedItems, function(item) {
return ko.utils.arrayFirst(self.availableItems(), function(itm) {
return item.UserName == itm.title();
});
}));
self.filteredItems = ko.dependentObservable(function() {
debugger;
var filter = this.filter().toLowerCase();
if (!filter) {
return this.availableItems();
} else {
return ko.utils.arrayFilter(this.availableItems(), function(item) {
return item.title().toLowerCase().indexOf(filter) !== -1;
});
}
alert(this.availableItems());
}, self);
// Operations
self.removeItem = function(removedItem) {
self.selectedItems.remove(removedItem);
};
}
var vm = new SelectableItemViewModel(initialData);
ko.applyBindings(vm);
Ajax调用
$.ajax({
type: 'GET',
url: "@Url.Action("GetAllUsersByRoleInUtility", "Home")",
data: { utilityId: currentUtilityId, roleId: currentRoleId },
dataType: 'json',
success: function (data) {
initialData[0].availableItems = data.availableItems;
initialData[1].selectedItems = data.selectedItems;
vm = new SelectableItemViewModel(initialData)
},
error: function (data) {
alert('Oops! something went wrong.');
}
});
我第一次使用 knockoutjs ,
请帮助解决此问题。
答案 0 :(得分:0)
当您通过ajax加载数据时,您需要决定如何更新UI后面的代码。一个重要的决定:
这是你正在尝试做的事情,而你几乎成功了。如果要在成功回调中创建新的视图模型,则必须确保将其包装在可观察的内容中。
与您的情况相关的(简化)示例:
// Construct the initial, empty UI
ko.applyBindings(new App());
function App() {
this.selectableListVM = ko.observable(new SelectableList([]));
// Later (using ajax), swap out the vm
setTimeout(function() {
this.selectableListVM(new SelectableList([1,2,3]));
}.bind(this), 3000);
};
function SelectableList(items) {
this.items = ko.observableArray(items);
};

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="with: selectableListVM">
<span data-bind="visible: !items().length">loading..</span>
<ul data-bind="foreach: items">
<li data-bind="text: $data"></li>
</ul>
</div>
&#13;
选项2有点难以实现,但可以更高效。您需要清楚地定义数据,模型和状态之间的边界。例如,可选项目可能不会更改,而选择执行。 E.g:
// Construct the initial, empty UI
var SelectableList = function() {
this.items = ko.observableArray([]);
// This is automatically updated when you update items via ajax
this.selectedItems = ko.pureComputed(function() {
return this.items().filter(function(item) {
return item.selected;
})
}, this);
};
SelectableList.prototype.loadItems = function() {
// timeout to mock ajax
setTimeout(function() {
this.items([
{ name: 1, selected: Math.random() > 0.5 },
{ name: 2, selected: Math.random() > 0.5 },
{ name: 3, selected: Math.random() > 0.5 },
]);
}.bind(this), 200);
}
ko.applyBindings(new SelectableList());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: selectedItems">
<li data-bind="text: name"></li>
</ul>
<button data-bind="click: loadItems">Load new state</button>
&#13;