Javascript 从 HTML 元素(例如 onclick 处理程序)调用 RequireJs 模块中的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10302724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling methods in RequireJs modules from HTML elements such as onclick handlers
提问by HostileFork says dont trust SE
I'm changing a project from an "old" browser-style module structure to a "new" browser-or-server-side-javascriptmodule structure with require.js.
我是从一个“老”浏览器风格的模块结构改变一个项目,一个“新”浏览器的或-服务器端JavaScript的模块结构require.js。
On the client I'm using an offsite hosted jQuery, so I started from the example they give in the "use priority config"technique of the README:
在客户端上,我使用的是异地托管 jQuery,所以我从他们在自述文件的“使用优先级配置”技术中给出的示例开始:
<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>
This is actually working all right. But I'd like to export functionality from main to the HTML webpage itself. For instance:
这实际上工作正常。但我想将主要功能导出到 HTML 网页本身。例如:
<a class="button" href="#" onclick="MyApi.foo();">
<img src="foo.png" alt="foo" />Click for: <b>Foo!</b>
</a>
Before fitting into the AMD module pattern, I'd exposed functionality from my various files by creating a dictionary object in the global space:
在适应 AMD 模块模式之前,我通过在全局空间中创建一个字典对象来从我的各种文件中公开功能:
// main.js
var MyApi = {};
jQuery(document).ready(function($) {
// ...unexported code goes here...
// export function via MyApi
MyApi.foo = function() {
alert("Foo!");
};
});
But I don't know what the right approach in require.js is. Is it okay to put in the HTML more require
statements inside of <script>
tags, and then name modules so that it can be used from within the webpage? Or should this always be done dynamically inside of main.js, like $('#foobutton').click(...)
?
但我不知道 require.js 中的正确方法是什么。是否可以在 HTML标签require
内添加更多语句<script>
,然后命名模块以便它可以在网页内使用?或者这应该总是在 main.js 内部动态完成,比如$('#foobutton').click(...)
?
采纳答案by Simon Smith
One benefit from using AMD is to drop the need for namespaces. Trying to create them again with RequireJS will go against the patterns AMD promotes.
使用 AMD 的一个好处是不再需要命名空间。尝试使用 RequireJS 再次创建它们将违背 AMD 提倡的模式。
With regard to using main.js
, this is only really appropriate when you have a single page app and all your code be reference from one place. You're free to make additional calls to require and load other modules as you need them.
关于使用main.js
,这仅在您拥有单页应用程序并且所有代码都可以从一个地方引用时才真正合适。您可以根据需要自由地进行额外的调用来要求和加载其他模块。
Using your example from above, you could approach it this way:
使用上面的示例,您可以通过以下方式进行处理:
foo.js
foo.js
define(['jquery'], function($) {
// Some set up
// code here
// Return module with methods
return {
bar: function() {
}
}
});
page.js
页面.js
require(['foo'], function(foo) {
// jQuery loaded by foo module so free to use it
$('.button').on('click', function(e) {
foo.bar();
e.preventDefault();
});
});
Then in your page request the page.js file with require.
然后在您的页面中使用 require 请求 page.js 文件。
Using your example above:
使用上面的示例:
require({
// config stuff here
}, [ 'page' ]);
Or loading it in the page further down:
或者在页面下方加载它:
<script>
require(['page']);
</script>
Some additional points
一些额外的点
Using the pattern above, page.js could easily require many other modules to load other page related functionality.
Where before you would attach members to your global namespace, you now split that code into separate modules that can be re-used on any page. All without reliance on a global object.
Using require this way to attach events to your DOM elements will most likely rely on the DOM Ready moduleprovided by RequireJS
使用上面的模式,page.js 可以很容易地需要许多其他模块来加载其他页面相关的功能。
之前将成员附加到全局命名空间的地方,现在将该代码拆分为可以在任何页面上重复使用的单独模块。所有这些都不依赖于全局对象。
使用 require 这种方式将事件附加到 DOM 元素很可能依赖于RequireJS 提供的 DOM Ready 模块
回答by jonperl
You can also set the reference on javascript's window class.
您还可以在 javascript 的窗口类上设置引用。
At the bottom of the application module window.MyApi = MyApi;
在应用模块底部 window.MyApi = MyApi;
<a class="button" href="#" onclick="MyApi.foo();"></a>
<a class="button" href="#" onclick="MyApi.foo();"></a>
回答by robrich
putting onclick=""
inside your markup feels dirty -- mixing presentation with content. I'd recommend you add a <script>
block and put the require
in it, and once inside the callback, and inside another inner $(document).ready()
if necessary then wire up your event handlers in the normal way: $('#node').click(...)
. If you can do this generically enough that it's applicable to multiple pages, then put it inside an external file that is minified, combined, and cached. But typically these things end up being page-specific, so a <script>
tag at the bottom of the page is a good solution to avoid yet another external resource request.
把onclick=""
你的标记放在里面感觉很脏——将演示与内容混合在一起。我建议你添加一个<script>
模块,并把require
它,一旦回调里面,里面的另一个内$(document).ready()
,然后根据需要接线了你的事件处理程序以正常方式:$('#node').click(...)
。如果您可以足够通用地执行此操作以使其适用于多个页面,则将其放入缩小、组合和缓存的外部文件中。但通常这些事情最终都是特定<script>
于页面的,因此页面底部的标签是避免另一个外部资源请求的好方法。
回答by feeeper
Another solution is just use code like that (of course requirejs
must be added to the page):
另一种解决方案是使用这样的代码(当然requirejs
必须添加到页面中):
<input type="button" onclick="(function() { require('mymodule').do_work() })()"/>