React/Flux Dispatcher作为Typescript中的Singleton



我正在TypeScript中重建Atlassian React+Flux教程(使用来自tsd的React、Flux和Node的绑定),但我在实现调度器时遇到了问题,它本质上是一个单例

我正在尝试以下操作:

AppDispatcher.ts

export var instance = AppDispatcher.getInstance();
class AppDispatcher extends Flux.Dispatcher<AppPayload> {
    private static _instance:AppDispatcher = new AppDispatcher();
    constructor() {
        super()
        if(AppDispatcher._instance){
            throw new Error("Error: Using this constructor should not be possible...WTH javascript");
        }
        AppDispatcher._instance = this;
    }
    public static getInstance():AppDispatcher
    {
        return AppDispatcher._instance;
    }
...
}

就像在教程中一样,我使用localStorage上的JSON文件来伪造web API。因此,我的ActionCreator会执行以下操作:

ActionCreator.ts

import AppDispatcherInstance = require('../dispatcher/AppDispatcher');
//ActionCreator
//In Flux ActionCreators
export function receiveAll(rawNodes:any) {
    AppDispatcherInstance.instance.handleServerAction(AppDispatcherInstance.ActionIdentifier.REFRESH_FROM_SERVER, rawNodes)
}

不幸的是,我得到了一个运行时异常未捕获类型错误:无法读取指向已传输Javascript行的未定义的属性"getInstance"

exports.instance = AppDispatcher.getInstance();
  1. 我在TypeScript中实现了singleton错误吗
  2. 总的来说,有更好的方法吗?我曾想过根本不编写类,只导出某些函数(就像其他SO问题中建议的那样)就可以编写到singleton,但我仍然想扩展Flux.Dispatcher类

以下是我如何在React/Flux项目中使用带有模块的单线态:

class AppDispatcher extends Flux.Dispatcher {
    // ...
}
export default new AppDispatcher();

单例可以导入到另一个文件中,如:

import AppDispatcher from "./AppDispatcher";
AppDispatcher.dispatch(...);

如果您需要导出类类型,您可以将export添加到class AppDispatcher,如果您需要在同一个文件中导入这两个类类型,则可以使用不同的名称导入singleton(我倾向于在单元测试中需要这一点):

import AppDispatcherInstance, {AppDispatcher} from "./AppDispatcher"

正如评论者所建议的,您需要将使用类的代码移动到该类的声明下方。类只是变量,JavaScript中的变量按顺序初始化。

通常,您不需要在TypeScript中使用显式类singleton模式。请参阅如何在TypeScript 中定义Singleton

无用的单例模式

class Singleton {
    /* ... lots of singleton logic ... */
    public someMethod() { ... }
}
// Using
var x = Singleton.getInstance();
x.someMethod();

命名空间等效

namespace Singleton {
    export function someMethod() { ... }
}
// Usage
Singleton.someMethod();
var x = Singleton; // If you need to alias it for some reason

最新更新