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

时间:2012-04-24 17:13:28

标签: javascript html module requirejs

我正在将项目从“旧”浏览器样式模块结构更改为“新”浏览器 - - 服务器端-javascript 模块结构require.js

在客户端我使用的是异地托管的jQuery,所以我从他们在自述文件的"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>

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

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

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

// main.js

var MyApi = {};

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

    // export function via MyApi
    MyApi.foo = function() {
        alert("Foo!");
    };
});

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

4 个答案:

答案 0 :(得分:31)

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

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

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

<强> foo.js

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

    // Some set up 
    // code here

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

        }
    }


});

<强> 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();
    });

});

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

使用上面的示例:

require({
    // config stuff here
}, [ 'page' ]);

或者在页面中进一步向下加载:

<script>
    require(['page']);
</script>

其他一些要点

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

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

  • 使用require这种方式将事件附加到DOM元素中 最有可能由RequireJS提供rely on the DOM Ready module

答案 1 :(得分:15)

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

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

的底部

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

答案 2 :(得分:3)

onclick=""置于您的标记中会感觉很脏 - 将演示文稿与内容混合在一起。我建议您添加一个<script>块并将require放入其中,一旦进入回调内部,并在必要时将另一个内部$(document).ready()放入其中,然后在正常情况下连接您的事件处理程序方式:$('#node').click(...)。如果您可以完全执行此操作以使其适用于多个页面,则将其放在缩小,组合和缓存的外部文件中。但通常这些内容最终都是特定于页面的,因此页面底部的<script>标记是避免另一个外部资源请求的好方法。

答案 3 :(得分:2)

另一种解决方案就是使用这样的代码(当然requirejs必须添加到页面中):

<input type="button" onclick="(function() { require('mymodule').do_work() })()"/>