从HTML元素(如onclick处理程序)调用RequireJs模块中的方法

Hos*_*ork 33 html javascript module requirejs

我是从一个"老"浏览器风格的模块结构改变一个项目,一个"新"浏览器的 - 服务器端JavaScript的模块结构require.js.

在客户端我使用的是异地托管的jQuery,所以我从他们在README 的"use priority config"技术中给出的示例开始:

<title>My Page</title>
<script src="scripts/require.js"></script>
<script>
require({
    baseUrl: 'scripts',
    paths: {
        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min',
        jqueryui: ...,
        ...
        ... // bunch more paths here
    },
    priority: ['jquery']
}, [ 'main' ]);
</script>
Run Code Online (Sandbox Code Playgroud)

这实际上是正常的.但我想将功能从main导出到HTML网页本身.例如:

<a class="button" href="#" onclick="MyApi.foo();">
    <img src="foo.png" alt="foo" />Click for: <b>Foo!</b>
</a>
Run Code Online (Sandbox Code Playgroud)

在适应AMD模块模式之前,我通过在全局空间中创建字典对象来从我的各种文件中公开功能:

// main.js

var MyApi = {};

jQuery(document).ready(function($) {
    // ...unexported code goes here...

    // export function via MyApi
    MyApi.foo = function() {
        alert("Foo!");
    };
});
Run Code Online (Sandbox Code Playgroud)

但我不知道require.js中的正确方法是什么.是否可以在标签require内添加HTML更多语句<script>,然后命名模块以便可以在网页中使用它?或者这应该始终在main.js中动态完成,比如$('#foobutton').click(...)

Sim*_*ith 31

使用AMD的一个好处是不再需要名称空间.尝试使用RequireJS再次创建它们将违背AMD推出的模式.

关于使用main.js,只有当您有一个页面应用程序并且所有代码都从一个地方引用时,这才是真正合适的.您可以根据需要随意拨打其他需要的模块.

使用上面的示例,您可以这样处理它:

foo.js

define(['jquery'], function($) {

    // Some set up 
    // code here

    // Return module with methods
    return {
        bar: function() {

        }
    }


});
Run Code Online (Sandbox Code Playgroud)

page.js

require(['foo'], function(foo) {

    // jQuery loaded by foo module so free to use it
    $('.button').on('click', function(e) {
        foo.bar();
        e.preventDefault();
    });

});
Run Code Online (Sandbox Code Playgroud)

然后在您的页面中请求带有require的page.js文件.

使用上面的示例:

require({
    // config stuff here
}, [ 'page' ]);
Run Code Online (Sandbox Code Playgroud)

或者将其加载到页面中:

<script>
    require(['page']);
</script>
Run Code Online (Sandbox Code Playgroud)

一些额外的要点

  • 使用上面的模式,page.js可能很容易需要许多其他模块来加载其他页面相关的功能.

  • 在将成员附加到全局命名空间之前,您现在将该代码拆分为可在任何页面上重复使用的单独模块.所有这些都不依赖于全局对象.

  • 使用require以这种方式将事件附加到DOM元素很可能依赖于 RequireJS提供的DOM Ready模块


jon*_*erl 16

您还可以在javascript的窗口类上设置引用.

在应用程序模块的底部 window.MyApi = MyApi;

<a class="button" href="#" onclick="MyApi.foo();"></a>