使用require.js,避免重复使用newing-up对象

时间:2014-01-26 15:48:04

标签: javascript requirejs amd

如果不使用Require.js之类的东西,当应用程序加载到用户的Web浏览器中时,我会实例化应用程序客户端控制器之类的东西。通过这种方式,在浏览器中,应用程序的生命周期内每个控制器都会保留一个实例。

当引入Require.js时,实现同样事物的惯用方法是什么?

1 个答案:

答案 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拉入模块流程的一部分..