require.js + backbone.js:如何组织带有initialize函数的模块?

4
我有一个包含三个页面的应用程序(这些页面是单页接口)。这些页面具有类似但不完全相同的功能。
所以我想要使用提供共同功能的javascript模块。然后每个页面可以自定义/覆盖共同功能的某些部分。
我正在使用backbone.js,我的做法是:
1.加载包含公共模型、视图、集合等的文件。 2.加载定制/覆盖步骤1的特定于应用程序的文件。 3.调用init()函数实例化所有必要的模型/视图/集合。
目前,我将我的模块存储在类似于以下链接中的模块容器中:https://stackoverflow.com/a/9426071。每个模块都有一个可选的init()函数,由我的主init()函数执行。
例如:
  1. I have a file called results.js. It defines the common Model/Collection/View of search-results. In its init() function everything is instanciated, but this function is not yet called:

    var resultView = new ResultView()
    
  2. Then I include myApp.js, and parts of the View are overwritten.

  3. The main init() function calls results.js init() which instanciates the new View. Everything works nice, smooth and DRY.
现在我想换成 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个模块和一些库,这并不美观也不符合DRY原则。是否有任何方法可以访问(循环遍历)require.js持有的所有模块?
或者我是不是错过了什么,应该以不同的方式构建我的代码?
欢迎任何提示/想法,
迈克尔

1
你有没有考虑在回调函数中简单地循环遍历 arguments,并在其中调用 init()(如果存在)? - chrisfrancis27
哪些arguments?如果你指的是这个: function(module1, module2, module3, ...) { 我怎么能在不显式命名它们的情况下循环遍历它们呢? - Michael
1
这就是它的全部 - arguments 对象function 的内置属性,它是传递给函数的所有参数的数组。在 require.js 的情况下,你知道接收到的参数将完全匹配你提供的依赖模块定义。 - chrisfrancis27
1
你刚刚增加了我对JavaScript的了解,谢谢!arguments看起来是一件非常基本的事情,我想知道为什么我以前从未阅读过它。这样,我甚至可以只明确命名一次模块,很棒。 - Michael
@ChrisFrancis如果您能将其作为回答写在问题上,那么对于SO来说会更好,Michael可以投票并接受它作为最佳答案。然后,它将出现在搜索中作为已回答的问题。 - John Munsch
1
@JohnMunsch 谢谢,我会把它作为答案发布! - chrisfrancis27
1个回答

4

如上方评论中所讨论的,您可以在函数体内使用 arguments 对象 循环遍历参数,从而避免明确引用函数的参数。 因此:

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

Becomes:

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()检查,因为出于许多原因,这是良好的实践。另外,在尝试调用它之前,你将看到对init是否为函数的明确检查。

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

顺便说一下,在架构层面上,我认为你描述的项目结构非常好 - 我在许多大型项目中使用它,从未让我失望。Require.js非常棒! :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接