取消选择for循环KnockoutJS中的复选框

时间:2015-01-12 09:10:29

标签: 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++) {
            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
               }
            }

   };
};

更新

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

function IndexVM() {
    var self = this;

    // Observable objects
    self.Path = ko.observable();
    self.Files = ko.observableArray([]);

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

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

       ko.utils.arrayForEach(self.selectedFiles(), function (file) {
           $.ajax({
               url: "Home/CreateAMLTest",
               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
           });
        });
    };
};

1 个答案:

答案 0 :(得分:2)

那是因为你的File.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
            });
        });
    };
}

注意:

  • File.Selected现在是一个可观察的。
  • 为方便起见,现在有一个SelectedFiles()计算,我想你也需要在其他地方使用它。如果你不这样做,它仍然在改进CreateAML()的语义。
  • 我从for循环切换到ko.utils.arrayForEach()。这样做会对CreateAML()的可读性产生积极影响,加上creating functions in a loop (like the callbacks to .ajax()) is not recommended in JavaScript(顺便提一下,你最好使用这种反模式 - 在你的回调中引用i,但在回调运行时,i不再包含你的想法即使没有遇到错误,你的循环也不会表现正常。)
  • 通过连接字符串构建JSON并不理想。使用纯方法更好(ko.toJSON({ File: ko.toJS(file) })
  • 我从“成功”回调切换到Ajax调用中的“延迟”语义。
  • 如果您不想手动将所有对象映射到其视图模型,请查看knockout's mapping plugin
  • 在绝大多数广泛采用的约定中,只有构造函数名称在JavaScript中为PascalCase,所有其他标识符都在camelCase中。因此它是IndexVM,但createAMLfilesselectedFiles。考虑转换。