我知道这已被多次询问,但没有一个回答我的问题。 我有以下内容: 我通过JSON获取数据到Javascript到二维数组。 当我加载网站时,表格显示为想要的。 现在当我单击一个按钮(仅用于测试)时,它正在从数组中更新一个值并在控制台中记录该数组,在那里我看到更改的数组。 问题是表中的更改没有显示出来。 当我只是向数组添加一个值时,它会显示在表中。 我做错了什么?
HTML:
var sorts = ko.observableArray([]);
$(function() {
var request = new XMLHttpRequest();
var formData = new FormData();
var responseElements = [];
request.open("POST", "scripts.php", true);
formData.append("action", "getSorts");
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
responseElements = JSON.parse(request.responseText);
sorts = convertList(responseElements);
ko.applyBindings(new AppViewModel(sorts));
}
}
request.send(formData);
});
function convertList(response) { //just the function to convert the json object to a more useful array
var names = [];
var ingredients = [];
var sorts = [];
for (var index = 0; index < response.length; index++) {
var name = response[index]['name'];
var ing = response[index]['ingName'];
if (names.indexOf(name) == -1) {
names.push(name);
}
if (ingredients.indexOf(ing) == -1) {
var nameIndex = names.indexOf(name);
if (ingredients[nameIndex] == undefined) {
ingredients[nameIndex] = ing;
} else {
ingredients[nameIndex] = ingredients[nameIndex] + ", " + ing;
}
}
}
for (var i = 0; i < names.length; i++) {
sorts[i] = {};
sorts[i]['name'] = names[i];
sorts[i]['ingName'] = ingredients[i];
}
return sorts;
}
function AppViewModel(data) {
var self = this;
self.sorts = data;
self.addPerson = function() {
console.log("click");
self.sorts[0]["name"] = "test"; //doesn't update table
//self.sorts.push({name: "qwer", ingName: "we"}); //works like expected
console.log(self.sorts);
};
}
JS:
GoogleChart
感谢。
答案 0 :(得分:2)
可观察数组仅监视添加到其中的项目,而不是项目本身,所以
self.sorts.push({name: "qwer", ingName: "we"}); //works like expected
有效,因为您正在获取可观察数组以添加其项目,但
self.sorts[0]["name"] = "test"; //doesn't update table
不起作用,因为可观察数组无法知道其中的项目已更改。为此,数组中项目的属性需要是可观察的。
在convertList中切换到:
for (var i = 0; i < names.length; i++) {
sorts[i] = {};
sorts[i]['name'] = ko.observable(names[i]);
sorts[i]['ingName'] = ko.observable(ingredients[i]);
}
它们必须通过调用可观察的setter方法来设置:
self.addPerson = function() {
console.log("click");
self.sorts[0]["name"]("test");
...
另外,你似乎还有其他一些问题。您可以在第一行将sorts定义为可观察数组,但是使用convertList的返回值覆盖它,这是一个普通数组,而不是可观察数组。
sorts = convertList(responseElements);
ko.applyBindings(new AppViewModel(sorts));
我删除第一行并创建排序作为可观察数组
function convertList(response) { //just the function to convert the json object to a more useful array
var names = [];
var ingredients = [];
var sorts = ko.observableArray([]);
...
答案 1 :(得分:2)
问题是当你绑定它时:
<td data-bind="text: $data.name"></td>
$data.name
不可观察,它是一个对象的简单属性,在这里创建:
sorts[i]['name'] = names[i];
Knockout会非常高兴地绑定这样的属性并显示它们,但是对它们的任何更新都不会被淘汰。相反,除了observableArray
之外,您还需要创建您希望能够更新可观察对象的任何单个属性:
sorts[i]['name'] = ko.observable(names[i]);
然后当你更新它时,淘汰赛会看到变化。但是请注意,你不能简单地只分配给属性,因为你只是覆盖了敲掉的observable并且它会丢失,而你需要用更新调用 observable:
self.sorts[0]["name"]("test");