如果不使用Require.js之类的东西,当应用程序加载到用户的Web浏览器中时,我会实例化应用程序客户端控制器之类的东西。通过这种方式,在浏览器中,应用程序的生命周期内每个控制器都会保留一个实例。
当引入Require.js时,实现同样事物的惯用方法是什么?
答案 0 :(得分:2)
我建议您在AMD模块中导出类 - 而不是实例。 E.g。
// controllers/some_controller.js
define(function (require) {
function SomeController() {};
SomeController.prototype.foo = function () {};
return SomeController;
});
然后在其他地方管理对象的生命周期,也许在您的app.js中执行类似
的操作// app.js
define(function (require) {
var SomeController = require("./controllers/some_controller");
var activeController;
...
router.on("/foo", function () {
if (activeController) {
activeController.destroy();
}
activeController = new SomeController();
});
});
或者如果你想让控制器成为单身人士,就像你说的那样,你可以做这样的事情
// app.js
define(function (require) {
var controllers = {
"some": require("./controllers/some_controller")
};
var controllerCache;
function getController(name) {
if (!controllerCache[name]) {
controllerCache[name] = new controllers[name]();
}
return controllerCache[name];
}
var activeController;
...
router.on("/foo", function () {
if (activeController) {
activeController.exit();
}
activeController = getController("some");
});
});
无论如何,这些都是非常复杂的例子,但我的主要观点是我建议在你的模块中导出类 - 而不是实例 - 这样你就可以控制你如何管理这些对象及其生命周期,这也有助于测试你可以要求类,存根,提供模拟依赖等等。(有关使用容器查找各种对象实例的更高级示例,请查看http://www.slideshare.net/mixonic/containers-di。他甚至给出了如何将其与AMD模块一起使用的示例)
希望这有所帮助。
<强>更新强> 当然,您也可以导出函数或具有函数的对象以及其他任何合适的对象,但很可能您不希望在模块的顶层实例化或执行操作 - 最好将其作为应用程序流程的一部分来执行,而不是require.js拉入模块流程的一部分..