knockout.js knockoutJS -未定义observableArray的元素

4dbbbstv  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(159)

我有一个名为self.species的observableArray,我正在向它推送2个神奇宝贝物种的数据(例如JSON:https://pastebin.com/a6DKFwaM)。当我执行console.log(self.species())时,我得到的是(https://i.imgur.com/mPRmKFm.png)。然而,当我执行console.log(self.species()[0])时,我得到的是undefined,而不是第一个神奇宝贝物种的数据。这是为什么呢?这是我的代码(在HTML中,我输入了data-bind=“value:self.species1”和数据绑定=“值:self.species2”和带有data-bind=“单击:获取物种”)

var self = this;
    var baseURL = 'http://0/pokemons/api/EggGroups/';
    self.displayName = 'Pokémon Breed Tester';
    self.error = ko.observable('');
    self.species = ko.observableArray([]);
    self.species1 = ko.observable();
    self.species2 = ko.observable();
    getSpecies = function () {
        self.species.removeAll();
        var URL1 = "http://0/pokemons/api/PokemonSpecies/" + self.species1();
        var URL2 = "http://0/pokemons/api/PokemonSpecies/" + self.species2();
        ajaxHelper(URL1, 'GET').done(function (data) {
            self.species.push(data);
        });
        ajaxHelper(URL2, 'GET').done(function (data) {
            self.species.push(data);
        });
        console.log(self.species());
        console.log(self.species()[0]); //Undefined
    }
    function ajaxHelper(uri, method, data) {
        self.error('');
        return $.ajax({
            type: method,
            url: uri,
            dataType: 'json',
            contentType: 'application/json',
            data: data ? JSON.stringify(data) : null,
            error: function (jqXHR, textStatus, errorThrown) {
                console.log("AJAX Call[" + uri + "] Fail...");
                self.error(errorThrown);
            }
        });
    }
euoag5mw

euoag5mw1#

这是因为你是异步获取数据的,而JS代码是同步执行的,所以当你执行console.log(self.species())时,self.species仍然包含一个空数组,数据在稍后到达,如果仅仅是几毫秒之后,开发人员工具足够聪明,能够识别出self.species()是一个表达式,并且当它改变时,它将重新计算它。在屏幕截图中,它显示了一个小的“i”图标,这将告诉你表达式刚刚被计算过。但是当你执行console.log(self.species()[0])时,你在控制台中看到的是self.species()[0] * 在那个时间点 * 的值,它实际上是未定义的。当self.species改变时,它不会在控制台中更新。
如果在回调完成后更改代码以记录self.species,您会注意到不同之处:

ajaxHelper(URL1, 'GET').done(function (data) {
    self.species.push(data);
    console.log(self.species());
    console.log(self.species()[0]);
});
ajaxHelper(URL2, 'GET').done(function (data) {
    self.species.push(data);
    console.log(self.species());
    console.log(self.species()[0]);
});

添加

如果您希望等待所有请求完成,可以使用jQuery.when(或使用本地Promise.all()):

$.when(ajaxHelper(URL1, 'GET'), ajaxHelper(URL2, 'GET')).done(function (data1, data2) {
    // Now both AJAX requests have been completed
    // And the return data is in the (terribly named) parameters
    self.species.push(data1, data2);
    // Now you can safely compare self.species()[0] to self.species()[1]
});

相关问题