打字稿单身设计模式:这是未定义的

时间:2017-05-04 19:47:09

标签: typescript design-patterns singleton nativescript

我已经在typescript(2.1.6)类中实现了单例模式,如下所示:

export class NotificationsViewModel {
    private _myService: NotificationService;
    private _myArray: [];
    private static _instance: NotificationsViewModel;
    private constructor() {
        this._myService = new NotificationService();
        this._myArray = [];
        NotificationsViewModel._instance = this;
    }
    public static getInstance(): NotificationsViewModel {
        if (!this._instance) {
            this._instance = new NotificationsViewModel();
        }
        return this._instance;
    }
    public startListening() {
        return this._myService.addUserNotificationChildListener(this.handleNotifications);
    }
    private handleNotifications(notification: Models.NotificationItem) {
        this._myArray.push(notification);// this line breaks
    }
}

有趣的是, handleNotifications方法失败,错误为cannot read property _myArray of undefined 。基本上它说this - 等于instance - 是不是即时的(正确吗?)。 我不明白这是怎么回事,因为this._myService没有任何问题。

我是否以错误的方式实施模式?为什么会这样?

修改 以下是调用类的代码:

    notificationsViewModel = NotificationsViewModel.getInstance(mainUser);
    notificationsViewModel.initialize().then(() => {
        notificationsViewModel.startListening();
    }).catch((error) => {
        console.dump(error);
    });

我在上面的代码段中没有包含initialize方法,但它会返回一个承诺。

1 个答案:

答案 0 :(得分:2)

所以这里的问题是经典的“错误的this上下文”,因为您传递的是对handleNotifications方法的引用,该方法未绑定到实例。

应该是:

public startListening() {
    return this._myService.addUserNotificationChildListener(this.handleNotifications.bind(this));
}

或者:

public startListening() {
    return this._myService.addUserNotificationChildListener(notification => this.handleNotifications(notification));
}

此外,您无需在构造函数中创建实例:

private constructor() {
    this._myService = new NotificationService();
    this._myArray = [];
    NotificationsViewModel._instance = this; // this is redundant
}