web-dev-qa-db-ja.com

onclickハンドラーなどのHTML要素からRequireJsモジュールのメソッドを呼び出す

プロジェクトを「古い」ブラウザスタイルのモジュール構造から「新しい」ブラウザに変更しています-or-require.js のserver-side-javascriptモジュール構造。

クライアントでは、オフサイトでホストされている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>
_

これは実際には大丈夫です。しかし、メインからHTML Webページ自体に機能をエクスポートしたいと思います。例えば:

_<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の正しいアプローチが何であるかわかりません。 HTMLの_<script>_タグ内にrequireステートメントを追加し、モジュールに名前を付けてWebページ内から使用できるようにすることはできますか?または、これは常に$('#foobutton').click(...)のようにmain.js内で動的に行われるべきですか?

34
HostileFork

AMDを使用する利点の1つは、名前空間の必要性がなくなることです。 RequireJSで再度作成しようとすると、AMDが推奨するパターンに反します。

main.jsの使用に関して、これは、単一ページのアプリがあり、すべてのコードが1か所から参照される場合にのみ本当に適切です。他のモジュールを必要に応じてロードするために、追加の呼び出しを自由に行うことができます。

上記の例を使用すると、次のようにアプローチできます。

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 this wayを使用してイベントをDOM要素にアタッチすると、おそらく DOM Readyモジュールに依存 RequireJSによって提供されます

31
Simon Smith

JavaScriptのウィンドウクラスに参照を設定することもできます。

アプリケーションモジュールの下部_window.MyApi = MyApi;_

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

16
jonperl

マークアップ内に_onclick=""_を配置すると、プレゼンテーションがコンテンツと混ざり合い、汚れた感じがします。 _<script>_ブロックを追加して、その中にrequireを配置し、必要に応じてコールバック内、および別の内部$(document).ready()内に配置してから、イベントハンドラーを接続することをお勧めします通常の方法:$('#node').click(...)。複数のページに適用できるほど一般的にこれを行うことができる場合は、縮小、結合、およびキャッシュされる外部ファイル内に配置します。しかし、通常、これらはページ固有のものであるため、ページの下部にある_<script>_タグは、別の外部リソース要求を回避するための優れたソリューションです。

3
robrich

別の解決策は、そのようなコードを使用することです(もちろんrequirejsをページに追加する必要があります):

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