Knockout.js 取消选择循环KnockoutJS中的复选框

Knockout.js 取消选择循环KnockoutJS中的复选框,knockout.js,Knockout.js,我试图根据结果取消选中每个复选框,但我得到一个错误,指出布尔值不是函数 视图模型 function IndexVM() { // Observable objects this.Files = ko.observableArray([]); this.CreateAML = function () { var self = this; for (var i = 0; i < self.Files().length; i++) {

我试图根据结果取消选中每个复选框,但我得到一个错误,指出布尔值不是函数

视图模型

function IndexVM() {
    // Observable objects
    this.Files = ko.observableArray([]);

    this.CreateAML = function () {
        var self = this;

        for (var i = 0; i < self.Files().length; i++) {
            if (self.Files()[i].Selected) {
               $.ajax({
                   type: "POST",
                   url: "Home/CreateAML",
                   dataType: 'json',
                   data: "{ 'File': " + ko.toJSON(self.Files()[i]) + "}",
                   contentType: "application/json",
                   success: function (response) {
                       self.Files()[i].Selected(response.d); //this is where the error is thrown
               }
            }

   };
};

这是因为您的
文件.Selected
在代码中不是可见的,它是一个纯布尔值

使其可见或使用
self.Files()[i].Selected=response.d来设置它。我建议前者

我还建议对代码进行一些其他更改:

function File() {
    var self = this;
    self.Selected = ko.observable(false);
    // ...more properties
}

function IndexVM() {
    var self = this;

    self.Files = ko.observableArray([]);

    self.SelectedFiles = ko.pureComputed(function () {
        return ko.utils.arrayFilter(self.Files(), function (file) {
            return file.Selected();
        });
    });

    this.CreateAML = function () {
        ko.utils.arrayForEach(self.SelectedFiles(), function (file) {
            $.ajax({
                type: "POST",
                url: "Home/CreateAML", 
                contentType: "application/json; charset=utf-8",
                data: ko.toJSON({
                    File: ko.toJS(file)
                })
            }).done(function (response) {
                file.Selected(response.d);
            }).fail(function (jqXHR, textStatus, errorThrown) {
                // handle the error
            });
        });
    };
}
注:

  • 文件。选定的
    现在是可观察的
  • 为了方便起见,现在有一个
    SelectedFiles()
    computed,我想您在其他地方也需要它。如果不这样做,它仍在改进
    CreateAML()
    的语义
  • 我从
    for
    循环切换到
    ko.utils.arrayForEach()
    。这样做对
    CreateAML()
    的可读性也有积极的影响,另外还有。(顺便说一句,您使用此反模式就是最好的证明——您在回调中引用了
    i
    ,但在回调运行时,
    i
    不再包含您认为它包含的内容。即使没有遇到错误,您的循环也不会正确运行。)
  • 通过连接字符串来构建JSON并不理想。使用纯方法更好(
    ko.toJSON({File:ko.toJS(File)})
  • 在Ajax调用中,我从“success”回调切换到了“deferred”语义
  • 如果不想手动将所有对象映射到其视图模型,请查看
  • 通过绝大多数广泛采用的约定,JavaScript中只有构造函数名是
    PascalCase
    ,所有其他标识符都在
    camelCase
    中。因此,它应该是
    IndexVM
    ,但
    createAML
    文件
    选定文件
    。考虑切换

感谢您提供的宝贵信息。我在这一行收到错误“undefined is not a function”:this.selectedFiles=ko.pureComputed(function(){您使用的是什么版本的敲除?如果低于3.2,请使用
computed()
而不是
pureComputed())
。已在3.2中引入。如果您不能使用它们,请不要介意,使用普通的。我使用的是3.0,因此我的理解是它应该可以工作。哎呀,我的错,它们已在3.2中引入。上面的注释已修复。感谢您的工作,但现在我遇到了相同的错误,即布尔值不是计算函数中的函数:return file.Selected();
function File() {
    var self = this;
    self.Selected = ko.observable(false);
    // ...more properties
}

function IndexVM() {
    var self = this;

    self.Files = ko.observableArray([]);

    self.SelectedFiles = ko.pureComputed(function () {
        return ko.utils.arrayFilter(self.Files(), function (file) {
            return file.Selected();
        });
    });

    this.CreateAML = function () {
        ko.utils.arrayForEach(self.SelectedFiles(), function (file) {
            $.ajax({
                type: "POST",
                url: "Home/CreateAML", 
                contentType: "application/json; charset=utf-8",
                data: ko.toJSON({
                    File: ko.toJS(file)
                })
            }).done(function (response) {
                file.Selected(response.d);
            }).fail(function (jqXHR, textStatus, errorThrown) {
                // handle the error
            });
        });
    };
}