我在每一行数据中有一个全选切换复选框和复选框。
现在从服务器返回的数据没有 isSelected
Observable。我为每一行添加了 'isSelected' observable。但是 isSelected
observable 不会绑定(bind)到每一行中的复选框。
这是 View 模型:
var folderViewModel = function () {
var self = this;
self.Folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.SelectedFolder = ko.observable();
self.Mails = ko.observableArray([]);
self.SelectedMail = ko.observable();
self.SelectAll = ko.observable(false);
self.navigate = function (folder) {
self.SelectedFolder(folder);
//$.get('/Api/MailBox', { folder: folder }, self.Mails);
$.ajax({
url: "/Api/Mailbox",
data: { folder: folder },
success: function (data) {
ko.mapping.fromJS(data, {}, self.Mails);
ko.utils.arrayForEach(self.Mails(), function (mail) {
mail.isSelected = ko.observable(true);
mail.isSelected.subscribe(function (myvalue) {
console.log(myvalue);
});
});
console.log(ko.toJSON(self.Mails()));
},
statusCode: {
404: function () {
alert("No Mail");
}
}
});
//ko.mapping.fromJS(data, {}, self.Mails);
//console.log(ko.toJSON(self.Mails));
};
self.SelectAll.subscribe(function (newValue) {
ko.utils.arrayForEach(self.Mails(), function (mail) {
console.log(mail.isSelected());
mail.isSelected(newValue);
});
console.log(newValue);
}, self);
this.navigate("Inbox");
};
ko.applyBindings(new folderViewModel());
这是绑定(bind)。
<table class="table table-bordered table-striped table-condensed table-hover">
<thead>
<tr>
<th>
<input type="checkbox" data-bind="checked: SelectAll"/>
@*<input type="checkbox" />*@
</th>
<th>
From
</th>
<th>
To
</th>
<th>
Subject
</th>
<th>
Date
</th>
</tr>
</thead>
<tbody data-bind="foreach:Mails">
<tr data-bind="click:$root.navigateToMail">
<td style="width: 15px">
<input type="checkbox" data-bind="checked: $root.isSelected">
@*<input type="checkbox">*@
</td>
<td data-bind="text: From">
</td>
<td data-bind="text: To">
</td>
<td data-bind="text: Subject">
</td>
<td data-bind="text: MailDate">
</td>
</tr>
</tbody>
<input type="checkbox" data-bind="checked: $root.isSelected">
复选框未绑定(bind)到 mails.isSelected=ko.obsevable(true)
中的 ajax 数据。可能是什么问题? 最佳答案
首先,赞誉使用 learn.knockoutjs.com 示例,惊人的资源。
您的错误是 KnockoutJS 中的一个常见陷阱:您正在修改模型而不更新绑定(bind)到它的 observables。请参阅以下几行 -
ko.mapping.fromJS(data, {}, self.Mails);
ko.utils.arrayForEach(self.Mails(), function (mail) { ... });
如果您看到,您首先为邮件创建模型,然后添加一个额外的可观察对象。这个 observable 应该附加到哪个上下文?在不更新每封邮件的值的情况下,您的
mail.isSelected
永远不会添加到邮件对象中。有两种方法可以解决这个问题。第一个,更新 forEach 数组中的邮件模型:
ko.utils.arrayForEach(self.Mails(), function (mail, index) {
// Add up the isSelected observable
self.Mails()[index] = mail;
});
这在您可以读取 here 的可观察数组上有一个性能问题。基本上,您希望创建一个临时数组并更新整个 observable 数组,而不是每次都调用
Mails()
。另一种方法非常简单:交换创建邮件模型的顺序:
ko.utils.arrayForEach(self.Mails(), function (mail) { ... });
ko.mapping.fromJS(data, {}, self.Mails);
首先,您将 observable 附加到一个数据对象,然后您告诉您的 View 模型“嘿!我们有一个新模型来保存它具有来自
data
的这个属性加上一个 observable isSelected 我刚刚添加,小心绑定(bind)它?话虽如此,HTML 中的属性是
checked: isSelected
而不是 checked: $root.isSelected
,这就是为什么它在 SelectAll(有点)上工作的原因,因为 isSelected 被绑定(bind)到您的 ViewModel 而不是您的邮件模型。你可以用这个方便的语句来解决调试问题:// In any row inside your data
<td data-bind="text: ko.toJSON($data)">DEBUG DATA</td>
应该是这样,您可以在这里看到您的代码及其所有解决方案: http://jsfiddle.net/jjperezaguinaga/VTuHA/ 。我添加了一些示例数据(使用来自 JsFiddle 的
/echo/json/
功能)并删除了一些东西,以及我用来调试最后一个代码的额外列。在最后一列中,您可以看到每次单击复选框时都会更新 isSelected
值。关于knockout.js - ajax调用成功后将viewmodel绑定(bind)到ui,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14092387/