我在每行数据中都有一个selectall切换复选框和复选框。
现在从服务器返回的数据没有isSelected
Observable。我为每一行添加了'isSelected'可观察对象。但是isSelected
可观察量并没有绑定到每行的复选框。
这是viewmodel:
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());
这是绑定。
<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">
未绑定到mails.isSelected=ko.obsevable(true)
中的ajax数据。可能是什么问题?
答案 0 :(得分:4)
首先,kuddos使用learn.knockoutjs.com示例,令人惊叹的资源。
您的错误是KnockoutJS中常见的陷阱:您正在修改模型而不更新绑定到它的可观察对象。请参阅以下行 -
ko.mapping.fromJS(data, {}, self.Mails);
ko.utils.arrayForEach(self.Mails(), function (mail) { ... });
如果你看到,你首先要为邮件创建模型,然后添加一个额外的可观察数据。这个观察应该附加到哪个上下文?如果不更新每封邮件的值,则mail.isSelected
永远不会添加到邮件对象中。
有两种方法可以解决这个问题。第一个,你在forEach数组中更新邮件模型:
ko.utils.arrayForEach(self.Mails(), function (mail, index) {
// Add up the isSelected observable
self.Mails()[index] = mail;
});
这对可观察数组有一个性能问题,您可以阅读here。基本上,您希望创建一个临时数组并更新整个可观察数组,而不是每次都调用Mails()
。
另一种方式很简单:交换如何创建邮件模型的顺序:
ko.utils.arrayForEach(self.Mails(), function (mail) { ... });
ko.mapping.fromJS(data, {}, self.Mails);
首先,你附加了一个你的observable数据对象,然后你告诉你的viewmodel“嘿!我们有一个新的模型来保存它具有来自data
的这个属性加上我刚刚添加的一个可观察的isSelected,小心绑定它?“
话虽如此,HTML中的属性是checked: isSelected
而不是checked: $root.isSelected
,这就是为什么它有点像SelectAll(排序)一样工作的原因,因为isSelected被绑定了到您的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
。
答案 1 :(得分:0)
每个isSelected
项目上都没有添加mail
,而不是root
视图模型中添加了<input type="checkbox" data-bind="checked: isSelected">
吗?如果是这样,你的绑定应该是:
navigateToMail
注意:我也没有在root
视图模型中看到{{1}}方法,这也会导致问题。