取消选中 for 循环 KnockoutJS 中的复选框
Deselect checkboxes in for loop KnockoutJS
我试图根据结果取消选择每个选中的复选框,但我收到一条错误消息,指出 boolean is not a function
ViewModel
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
});
});
};
};
那是因为您的 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 调用中从 "success" 回调切换到 "deferred" 语义。
- 如果您不想手动将所有对象映射到它们的视图模型,请查看 knockout's mapping plugin。
- 根据绝大多数广泛采用的约定,只有 构造函数 名称在 JavaScript 中为
PascalCase
,所有其他标识符在 camelCase
中。所以它将是 IndexVM
,但是 createAML
、files
和 selectedFiles
。考虑转行。
我试图根据结果取消选择每个选中的复选框,但我收到一条错误消息,指出 boolean is not a function
ViewModel
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
});
});
};
};
那是因为您的 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 调用中从 "success" 回调切换到 "deferred" 语义。
- 如果您不想手动将所有对象映射到它们的视图模型,请查看 knockout's mapping plugin。
- 根据绝大多数广泛采用的约定,只有 构造函数 名称在 JavaScript 中为
PascalCase
,所有其他标识符在camelCase
中。所以它将是IndexVM
,但是createAML
、files
和selectedFiles
。考虑转行。