无法在打字稿中将一个数组分配给另一个数组
not able to assign an array to another array in typescript
我已将风筝项定义为私有 kitems:any[];在 class。但是无法使用 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);
}
在您的代码中,您使用的是 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
并且尽量不要使用 bind
: https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html
当您将侦听器附加到 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");
}
输出将是:
Start listening
After listener
Got value
这可能不是您所期望的。但它是现代基于互联网编程的本质所固有的。大多数 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));
}
不是只有在数据从服务器返回后才会记录风筝项。更好的是:Firebase 数据库会同步数据,因此每次数据更改时您的回调都会 运行 .
由于将需要风筝项的代码放入回调中可能会损害可重用性,因此通常将回调函数传递到数据加载代码中。
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()
函数的回调非常相似,但会针对您的用例进行定制。
我已将风筝项定义为私有 kitems:any[];在 class。但是无法使用 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);
}
在您的代码中,您使用的是 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
并且尽量不要使用 bind
: https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html
当您将侦听器附加到 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");
}
输出将是:
Start listening
After listener
Got value
这可能不是您所期望的。但它是现代基于互联网编程的本质所固有的。大多数 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));
}
不是只有在数据从服务器返回后才会记录风筝项。更好的是:Firebase 数据库会同步数据,因此每次数据更改时您的回调都会 运行 .
由于将需要风筝项的代码放入回调中可能会损害可重用性,因此通常将回调函数传递到数据加载代码中。
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()
函数的回调非常相似,但会针对您的用例进行定制。