Javascript 模块模式和子模块初始化模式

发布于 2024-10-18 20:37:54 字数 1084 浏览 0 评论 0原文

我正在启动一个新项目,我正在回顾我的最佳实践,以试图防止出现任何问题,并看看我养成了哪些坏习惯。

我对如何使用模块/子模块模式处理 Javascript 中的初始化序列不太满意。

比方说,我的代码最终会

FOO.init()
FOO.module1.init()
FOO.module2.init()
FOO.module3.init()
FOO.module4.init()

在全局范围内得到类似的结果。

我本质上是在做(为简洁起见,省略了错误检查和细节):

var FOO = (function (me) {
    me.init = function () {
        for (var i in me.inits) {
            me.inits[i]();
        }
    }

    return me; 
}(FOO || {}));

var FOO = (function (parent) {
    var me = parent.module1 = parent.module1 || {};

    me.init = function () {
    }

    parent.inits.push(me.init);

    return parent;
}(FOO || {}));

$(document).ready(FOO.init);

用于初始化。

我知道我之前已经阅读过此内容,但我现在无法想出正确的搜索词来查找这些文章。是否有一个经过深思熟虑和经过测试的模式可以处理这样的情况下的初始化?

谢谢。

编辑:重新阅读本文后,我认为一些上下文可以提供答案。

就我而言,每个模块/子模块都在自己的文件中。基本模块定义了站点的基本功能,子模块启用不同的功能。例如,一个子模块可以在搜索框上连接自动完成功能,另一个子模块可以将静态标题图像转换为旋转横幅。子模块由 CMS 启用/禁用,因此我确实希望分离基本模块内的显式调用,以便一切都可以由 CMS 管理。我还认为有 CMS 特定的方法可以实现此目的,但我正在寻找一种通用的 Javascript 模式来实现此目的,以便在可能使用不同 CMS 的项目之间提供一致性和可重用性。

I am starting up a new project and I am reviewing my best-practices to try to prevent any problems, and also to see what bad habits I have gotten into.

I am not terribly pleased with how I am handling initialization sequences in Javascript using the module / submodule pattern.

Let's say, my code ends up with something like

FOO.init()
FOO.module1.init()
FOO.module2.init()
FOO.module3.init()
FOO.module4.init()

at the global scope.

I am essentially doing (error checking and details omittied for brevity):

var FOO = (function (me) {
    me.init = function () {
        for (var i in me.inits) {
            me.inits[i]();
        }
    }

    return me; 
}(FOO || {}));

var FOO = (function (parent) {
    var me = parent.module1 = parent.module1 || {};

    me.init = function () {
    }

    parent.inits.push(me.init);

    return parent;
}(FOO || {}));

$(document).ready(FOO.init);

for initialization.

I know I have read up on this before, but I can't come up with the right search terms to find the articles now. Is there a well thought out and tested pattern that handles initialization in sitiation like this?

Thanks.

EDIT: Upon re-reading this, I think a little context will inform answers.

In my case, each module / submodule is in its own file. The base module defines the basic functionality of the site, and sub-modules enable different features. For example, a sub-module may wire up auto-completion on a search box, and another may turn a static header image into a rotating banner. Sub-modules are enabled/disabled by the CMS, so I really do want to divorce explicit calls inside the base module so everything can be managed by the CMS. I also that there are CMS specific ways to accomplish this, but I looking for a generic Javascript pattern for doing this to provide consistency and resuablity between projects that may use a different CMS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葵雨 2024-10-25 20:37:54

我个人有不同的编码风格。这是其中之一。另一个基本上是对 backbone.js 中使用的样式的模仿

var myProgram = (function() {
   var someGlobal, someGlobal2;   

   var subModule1 = (function() {
       ...       

       var init = function() {

       };

       ...

       init();

       return { 
           "someMethod": someMethod,
           ...
       };
   }());

   var OtherSubModule = (function() {
       ...
       var init = function(param) { ... };
       ...
       return { 
           "init": init,
           ...
       };
   }());

   var init = function(param) {
       ...

       OtherSubModule.init({
           "foo": param.foo,
           "bar": param.bar,
           ...
       });
   };


   return { 
       "init": init,
       "somePublic": OtherSubModule.foobar, 
       ...
   }
}());

取决于我是否需要向其他用户提供公共 API,哪个主干网做得更好。我更喜欢让模块由 init 函数驱动来进行初始配置,其余部分则完全由事件驱动。

[编辑]

鉴于已编辑的问题,我对此有不同的模式。每个文件都在某个对象上定义一个函数,在我的例子中它是 $.FooBar.plugins

(function() {

    var foo = function() { ... };

    var bar = (function() { ... }());

    myNamespace.plugins["MyPlugin"] = function() {

        ... do stuff
        ... bind to evevnts
    };

}());

然后我们使用一个类似这样的引导捆绑器:

(function() {

    var needed = function() {
         // Feature detection
    };

    var load = function() { ... };

    var getOptions = function() {
         // Call something on a page by page basis.
    };

    for (var plugin in pluginList) {
         if (needed(plugin)) {
               load(plugin, function() {
                    // get page specific options
                    var options = getOptions();
                    // run plugin
                    myNameSpace.plugins[plugin](options);
                    // If all have been loaded trigger ready handlers
                    if (pluginCurrentCount == pluginCount) {
                         readyTrigger();
                    }
               });
               pluginCount++;
         }
    }

    // start loading plugins after all have been counted
    load.startLoading();

    var readyTrigger = function() {
         // Run all ready handlers
    }

    // Implement your own DOM ready function to run when all plugins
    // have loaded.
    myNameSpace.ready = function(handler) {
         if (isReady) {
             handler();
         } else {
             readyList.push(handler);
         }

    };
}());

这是很多间隙和伪代码,但你应该得到主意。如果不是显而易见的,请质疑它。

然后在页面上我们有这样的东西

<html>
<head>
  <script type="text/javascript">

    var pageSpecific = {
         "pluginName": {
              "cssClass": "foobar",
              "submitOnEnter": false,
              ...
         },
         ...
    };

  </script>
  <script src="bootstrapper.js" />
  ...
</head>
<body>
  ...
</body>
</html>

I personally have a different coding style to that. This is one of them. The other is basically an imitation of the style used in backbone.js

var myProgram = (function() {
   var someGlobal, someGlobal2;   

   var subModule1 = (function() {
       ...       

       var init = function() {

       };

       ...

       init();

       return { 
           "someMethod": someMethod,
           ...
       };
   }());

   var OtherSubModule = (function() {
       ...
       var init = function(param) { ... };
       ...
       return { 
           "init": init,
           ...
       };
   }());

   var init = function(param) {
       ...

       OtherSubModule.init({
           "foo": param.foo,
           "bar": param.bar,
           ...
       });
   };


   return { 
       "init": init,
       "somePublic": OtherSubModule.foobar, 
       ...
   }
}());

Depends whether I need to supply a public API to other users, which backbone does a lot better. I prefer to make modules driven by an init function for initial configuration and for the rest completely event driven.

[Edit]

Given the edited question I have a different pattern for this. Each file defines a function on some object in my case it was $.FooBar.plugins

(function() {

    var foo = function() { ... };

    var bar = (function() { ... }());

    myNamespace.plugins["MyPlugin"] = function() {

        ... do stuff
        ... bind to evevnts
    };

}());

Then we use a boot strapper that was something like this :

(function() {

    var needed = function() {
         // Feature detection
    };

    var load = function() { ... };

    var getOptions = function() {
         // Call something on a page by page basis.
    };

    for (var plugin in pluginList) {
         if (needed(plugin)) {
               load(plugin, function() {
                    // get page specific options
                    var options = getOptions();
                    // run plugin
                    myNameSpace.plugins[plugin](options);
                    // If all have been loaded trigger ready handlers
                    if (pluginCurrentCount == pluginCount) {
                         readyTrigger();
                    }
               });
               pluginCount++;
         }
    }

    // start loading plugins after all have been counted
    load.startLoading();

    var readyTrigger = function() {
         // Run all ready handlers
    }

    // Implement your own DOM ready function to run when all plugins
    // have loaded.
    myNameSpace.ready = function(handler) {
         if (isReady) {
             handler();
         } else {
             readyList.push(handler);
         }

    };
}());

That's a lot of gaps and pseudo code but you should get the idea. If it's not obvouis feel to question it.

Then on the page we have something like this

<html>
<head>
  <script type="text/javascript">

    var pageSpecific = {
         "pluginName": {
              "cssClass": "foobar",
              "submitOnEnter": false,
              ...
         },
         ...
    };

  </script>
  <script src="bootstrapper.js" />
  ...
</head>
<body>
  ...
</body>
</html>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文