无法将数组分配给typescript中的另一个数组

时间:2016-07-25 09:01:07

标签: arrays typescript firebase firebase-realtime-database ionic2

我将kitems定义为私人风筝:任何[];在课堂里。但是无法使用this.kitems = items为其分配任何值;当我执行console.log(this.kitems)时,我得到一个空数组。

createprofile() {
    this._UserRef.on("value", function(snapshot) {
        let items = [];
        snapshot.forEach(function(childSnapshot) {
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        });
        console.log(items[0].key);
        this.kitems = items;
    }.bind(this));
    console.log(this.kitems);
}

2 个答案:

答案 0 :(得分:0)

在您的代码中,您使用的是this。你很可能错了this。使用箭头功能:

createprofile = () => {
    this._UserRef.on("value", (snapshot) => {
        let items = [];
        snapshot.forEach((childSnapshot) => {
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        });
    console.log(items[0].key);
    this.kitems = items;
    });
console.log(this.kitems);
}

更多

https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

尽量不要使用bindhttps://basarat.gitbooks.io/typescript/content/docs/tips/bind.html

答案 1 :(得分:0)

将监听器附加到Firebase数据库(在您的情况下为on())时,启动从数据库加载数据。由于这可能需要一些时间,因此JavaScript代码将继续执行,并且您的代码将打印出空数组。然后,当数据从服务器变为可用时,将调用您的回调并将数据添加到数组中。

如果添加一些日志语句,通常最容易遵循:

createprofile() {
    console.log("Start listening");
    this._UserRef.on("value", function(snapshot) {
        console.log("Got value");
        let items = [];
        snapshot.forEach(function(childSnapshot) {
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        });
        this.kitems = items;
    }.bind(this));
    console.log("After listener");
}

输出将是:

  

开始聆听

     

听众之后

     

有价值

这可能不是你所期望的。但它是现代互联网编程本质所固有的。大多数API都会遇到这种行为。

一个常见的技巧是在处理这种所谓的异步API时以不同的方式构建代码。使用传统编程,您经常编写“首先获得A,然后执行B”。使用异步API,将其框定为“当我们得到A时,我们用它做B”。在您的代码中,这意味着您将需要kitems 的代码移动到回调函数中:

createprofile() {
    this._UserRef.on("value", function(snapshot) {
        let items = [];
        snapshot.forEach(function(childSnapshot) {
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        });
        this.kitems = items;
        console.log(this.kitems);
    }.bind(this));
}

一旦数据从服务器返回,就不会记录kitems。更好的是:Firebase数据库会同步数据,因此每次数据更改时都会运行

由于将需要kitems的代码放入回调中可能会损害可重用性,因此将回调函数传递给数据加载代码是很常见的。

createProfileAndThen(callback) {
    this._UserRef.on("value", function(snapshot) {
        let items = [];
        snapshot.forEach(function(childSnapshot) {
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        });
        this.kitems = items;
        callback(this.kitems);
    }.bind(this));
}

createProfileAndThen(function(kitems) {
    console.log(kitems);
});

这与您传递到Firebase的on()函数的回调非常相似,但后来根据您的用例进行了调整。