无法访问回调函数

时间:2017-03-06 03:47:35

标签: angular typescript firebase firebase-realtime-database

为了演示目的,我在我的app.component.ts中在我的构造函数之前声明了以下内容

private testObjArray = []

在我的ngOnInit中,我有以下

ngOnInit() {

    console.log('test 1', this.testObjArray);

    this.testObjArray = [1];

    console.log('test 2', this.testObjArray);

    this.databaseService.getNotification()
    .on('child_added', function (obj) {
        console.log('test 3', this.testObjArray); // <--- this is where the problem is
    })
}

在我的database.service.ts

里面
getNotificationsForCurrentUser() {
    let currentUser = this.userService.getCurrentUser()
    let ref = firebase.database().ref('notifications/')
    return ref;
}

在这种情况下,我确信.on会被触发,因为我的数据库中有数据。 我发现INSIDE从firebase中的getNotifications()回调,我似乎无法在我的应用程序顶部声明我的任何属性 例如,上述代码的控制台输出是

test 1 []
test 2 [1]
FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot read property 'testObjArray' of null
EXCEPTION: Cannot read property 'testObjArray' of null

我需要在我的.getNotification()。函数中引用this.testObjArray,以便我可以更新我的模板

3 个答案:

答案 0 :(得分:1)

您在函数中使用的this实际上是函数对象,因此您可以将其设置为函数外部的变量,以获得对所需this的访问权限。你正在创建一个闭包,所以这是你访问它的this的上下文问题。

ngOnInit() {

    console.log('test 1', this.testObjArray);

    this.testObjArray = [1];

    console.log('test 2', this.testObjArray);

    var that = this;

    this.databaseService.getNotification()
    .on('child_added', function (obj) {
        console.log('test 3', that.testObjArray); 
    })
}

答案 1 :(得分:1)

问题是你的回调函数中的this不是你的类上下文;它被绑定到触发事件的对象。

要解决此问题,您可以使用ES6 arrow functions来捕获正确的this

ngOnInit() {

    console.log('test 1', this.testObjArray);

    this.testObjArray = [1];

    console.log('test 2', this.testObjArray);

    this.databaseService.getNotification()
    .on('child_added', (obj) => { // Notice arrow function here
        console.log('test 3', this.testObjArray); //
    })
}

另一种选择是在回调之前捕获this变量:

ngOnInit() {

    console.log('test 1', this.testObjArray);

    this.testObjArray = [1];

    console.log('test 2', this.testObjArray);
    let that = this; // Capture `this` here
    this.databaseService.getNotification()
    .on('child_added', function (obj) {
        console.log('test 3', that.testObjArray); // ... and use it here
    })
}

答案 2 :(得分:0)

您需要绑定this

function (obj) {
    console.log('test 3', this.testObjArray); // <--- this is where the problem is
}.bind(this)

或者,您始终可以使用作为es6构造的lambda表达式(箭头函数)。

(obj) => console.log('test 3', this.testObjArray)