我正在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();
- 我在TypeScript中实现了singleton错误吗
- 总的来说,有更好的方法吗?我曾想过根本不编写类,只导出某些函数(就像其他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