我在每一行数据中有一个全选切换复选框和复选框。

现在从服务器返回的数据没有 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/

10-12 01:27