4

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

现在从服务器返回的数据没有isSelectedObservable。我为每一行添加了 'isSelected' observable。但是isSelectedobservable 不会绑定到每行中的复选框。

这是视图模型:

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). 可能是什么问题?

4

2 回答 2

4

首先,感谢使用learn.knockoutjs.com示例,令人惊叹的资源。

您的错误是 KnockoutJS 中的常见缺陷:您正在修改模型而不更新绑定到它的 observables。请参阅以下几行 -

ko.mapping.fromJS(data, {}, self.Mails);
ko.utils.arrayForEach(self.Mails(), function (mail) { ... });

如果您看到,您首先为邮件创建模型,然后添加一个额外的 observable。这个 observable 应该附加到哪个上下文?如果不更新每封邮件的值,mail.isSelected则永远不会将您添加到邮件对象中。

有两种方法可以解决这个问题。第一个,更新 forEach 数组中的邮件模型:

ko.utils.arrayForEach(self.Mails(), function (mail, index) { 
    // Add up the isSelected observable
    self.Mails()[index] = mail; 
});

这对可观察数组有一个性能问题,您可以在此处阅读。基本上,您想要创建一个临时数组并更新整个可观察数组,而不是Mails()每次调用。

另一种方法非常简单:交换创建邮件模型的顺序:

ko.utils.arrayForEach(self.Mails(), function (mail) { ... });
ko.mapping.fromJS(data, {}, self.Mails);

首先,您将附加到您的 observable 的数据对象,然后您告诉您的 viewmodel “嘿!我们有一个新模型来保存它,它具有来自dataPLUS 一个 observable isSelected 我刚刚添加的这个属性,要绑定它吗?”

话虽这么说,HTML 中的属性 ischecked: isSelected和 not 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/。我添加了一些示例数据(使用/echo/json/JsFiddle 的功能)并删除了一些东西,以及我用来调试的最后一个代码的额外列。在最后一列中,您可以看到isSelected每次单击复选框时都会更新值。

于 2012-12-30T17:34:33.247 回答
0

是不是isSelected在每个mail项目上添加,不在root视图模型中?如果是这样,您的绑定应该是:

<input type="checkbox" data-bind="checked: isSelected">

注意:我也没有navigateToMail在视图模型中看到可用的方法root,这也会导致问题。

于 2012-12-30T16:43:05.393 回答