【问题标题】:require.js + backbone.js: How to structure modules that have an initialize function?require.js +bone.js:如何构造具有初始化功能的模块?
【发布时间】:2012-07-31 12:54:00
【问题描述】:

我有一个包含三个页面的应用程序(它们是单页界面)。这些页面具有相似但不相同的功能。

所以我想要提供通用功能的 javascript 模块。然后每个页面都可以自定义/覆盖部分通用功能。

我正在使用backbone.js,所以我要做的是:

  1. 加载包含常见模型、视图、集合等的文件。
  2. 加载自定义/覆盖第 1 步部分的应用特定文件
  3. 调用一个 init() 函数来实例化所有必要的模型/视图/集合

目前,我将模块存储在类似于以下内容的模块容器中:https://stackoverflow.com/a/9426071 每个模块都有一个可选的 init() 函数,由我的主 init() 函数执行。

例子:

  1. 我有一个名为 results.js 的文件。它定义了搜索结果的通用模型/集合/视图。在它的 init() 函数中,一切都被实例化了,但是这个函数还没有被调用:

    var resultView = new ResultView()
    
  2. 然后我包含 myApp.js,部分视图被覆盖。

  3. 主 init() 函数调用 results.js init() 实例化新视图。一切正常、顺畅、干燥。

现在我想切换到 require.js 而不是我自己的模块容器,想知道如何组织我的代码。

我可以在 myApp.js 中实例化所有模型/视图等,而不是每个模块的 init() 函数。这意味着有很多重复的代码。

或者我可以坚持每个模块都有它的 init() 函数,并在 myApp.js 中调用这些 init() 函数。我不喜欢这样,因为我必须为我的三个页面中的每一页明确写下我的模块三次:

require(['module1', 'module2', 'module3', ...],
  function(module1, module2, module3, ...) {
    var init = function() {
      module1.init();
      module2.init();
      module3.init();
      ...
    }
    return {init: init};
  }
);

对于 10 个模块和一些库,这不是很好而且很枯燥。有什么方法可以访问(循环) require.js 拥有的所有模块?

或者我遗漏了什么,我应该以不同的方式构建我的代码吗?

欢迎任何提示/想法,

迈克尔

【问题讨论】:

  • 你有没有想过在你的回调中简单地循环arguments并调用init()(如果存在)?
  • 究竟是哪个arguments?如果你的意思是:function(module1, module2, module3, ...) {我如何在不明确命名的情况下循环它们?
  • 就是这样 - arguments objectfunction 的内置属性,它是传递给函数的所有参数的数组。对于 require.js,您知道收到的参数将与您作为依赖项提供的模块定义完全匹配。
  • 您刚刚提高了我对 JavaScript 的了解,谢谢! arguments 似乎是一个非常基本的东西,我想知道我怎么从来没有读过它。这样我什至可以明确地为模块命名一次,非常好。
  • @JohnMunsch 谢谢,我会把它作为答案发布!

标签: javascript backbone.js requirejs js-amd


【解决方案1】:

正如上面 cmets 中所讨论的,您可以通过在函数体内使用 arguments object 循环遍历函数的参数来避免显式引用函数的参数。所以:

require(['module1', 'module2', 'module3', ..., 'moduleN'],
  function(module1, module2, module3, ..., moduleN) {
    var init = function() {
        module1.init();
        module2.init();
        module3.init();
        ...
        moduleN.init();
    };
    return {init: init};
});

变成:

require(['module1', 'module2', 'module3', ..., 'moduleN'],
  function() {
    var args = arguments;
    var init = function() {
        var module;
        for (module in args) {
            if (args.hasOwnProperty(module) && typeof module.init === 'function') {
                module.init.call(this);
            }
        }
    };
    return {init: init};
});

我在for in 循环内添加了hasOwnProperty() 检查,因为出于多种原因,它是good practice。此外,在尝试调用 init 之前,您会看到显式检查它是一个函数。

var args = arguments 的原因是您可以从内部函数中引用它 - 否则您将引用传递给 init() 的参数,这不是您想要的。

顺便说一句,在架构层面上,我认为您所描述的项目结构效果非常好 - 我在很多非常大的项目中使用它,它从未让我失望。 Require.js 太棒了! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    相关资源
    最近更新 更多