2017-07-18 6 views
0

モジュールを1ページで2回、それぞれ異なるデータで使用したい。私の場合は、例えば、2回使用された口ひげテンプレート、モジュールが必要です。私の口ひげテンプレートでrequireJSモジュールが含まれている瞬間にロードする方法

{{> template-requiretest }} 
{{> template-requiretest }} 

を、私はこのようなものだ:init関数呼び出しで

<script> 
    var data1 = [x,y,z]; 
    var data2 = [x,y,z]; 
    var theId = (some random id); 

    require(['app/myApp'], function(myApp){ 
     myApp.init(); 
    }); 
</script> 

を私は "myApp"をdata1配列とdata2配列で別々に2回実行することを期待していましたが、 "myapp"内のconsole.logで単純にテストした "myapp.init()"は一度だけ実行されます。

コードは単に間違っていますか、またはAMD/requireJSがどのように動作するのか迷っていますか?

EDIT:さらにテスト:

var random = Math.floor((Math.random() * 1000) + 1); 
var el = document.getElementById('someId'); 
el.id += '-'+random; 
var theId = el.id; 
console.log("ID, set in mustache: ",theId); 

require(['app/myApp'], function(myApp){ 
    console.log("ID, logged inside reqJS:",theId); 

    myApp.init(); 
}); 

そして、コンソール出力はこれです:

xyz.html:131 ID, set in mustache: someId-428 
xyz.html:181 ID, set in mustache: someId-248 
myApp.js:3 ##### running the script now ##### 
myApp.js:4 ##### using ID: someId-248 ##### 
xyz.html:134 ID, logged inside reqJS: someId-248 
xyz.html:184 ID, logged inside reqJS: someId-248 

口ひげテンプレートが2回ロードしまった後にこれは、モジュールがロードされていることを示し、最後に生成されたIDのみでmyApp.jsのスクリプトを2回実行しています。

答えて

1

require(['app/myApp'], function(myApp){を実行するたびに、RequireJSは、app/myAppがロードされるとコールバックを実行するように指示します。モジュールがまだフェッチされていない場合、RequireJSはフェッチを開始し、コールバックを記録し、フェッチが終了してモジュールがインスタンス化されると、コールバックをコールします。モジュールがインスタンス化される前に、同じモジュールに対する複数の要求が来ると、RequireJSは、モジュールが最終的に使用可能になったときに呼び出す必要があるコールバックを追跡します。あなたのログにはと表示されます。これはあなたのケースで起こることです

私は、あなたが直感的に期待するか、希望する実行のこの順序だと思う:

  1. var theId = el.id;someId-428からtheIdを設定し、実行します。
  2. require(['app/myApp'], function(myApp){が実行されます。
  3. console.log("ID, logged inside reqJS:",theId);が実行され、someId-428が表示されます。
  4. var theId = el.id;theIdからsomeId-248に設定して実行します。
  5. require(['app/myApp'], function(myApp){が実行されます。
  6. console.log("ID, logged inside reqJS:",theId);が実行され、someId-248を示します。

しかし、本当の実行順序、このようなものです:

  1. var theId = el.id;実行、someId-428theIdを設定します。
  2. require(['app/myApp'], function(myApp){が実行され、RequireJSがapp/myAppのロードを開始し、コールバックをコールして将来コールします。
  3. var theId = el.id;theIdからsomeId-248に設定して実行します。
  4. require(['app/myApp'], function(myApp){が実行されますが、モジュールがまだロードされていないため、RequireJSはapp/myAppがロードされたときに呼び出されるコールバックを追加します。
  5. app/myAppが最後にロードされるため、コールバックは2回呼び出されます。ただし、このときまでにtheIdの値はsomeId-248です。

最後のステップについては、両方のコールバックが同じ変数にアクセスしていることをノードにすることが重要です。あなたのコードがscriptの要素の場合、var theIdのグローバルという変数を宣言しています。強制的に、両方のコールバックが同じ変数にアクセスしている必要があります。グローバル変数theIdにアクセスしてIDを取得する場合は、myApp.init()と同じです。

IIFEでこの問題を回避し、idをmyApp.init()呼び出しに渡して、その関数のコード内のパラメータを使用することができます。だから、:上記のコードはtheIdが呼び出されるたびに新しい変数は、生命維持にスコープされるように

(function() { 
    var random = Math.floor((Math.random() * 1000) + 1); 
    var el = document.getElementById('someId'); 
    el.id += '-'+random; 
    var theId = el.id; 
    console.log("ID, set in mustache: ",theId); 

    require(['app/myApp'], function(myApp){ 
    console.log("ID, logged inside reqJS:",theId); 

    myApp.init(theId); // Pass the id to your function. 
    }); 
}()); 

生命維持には、それを作ります。したがって、RequireJSによって呼び出されるコールバックは、それぞれ独自の別個の値を持つ独自の別個の変数を参照します。

0

require(['app/myApp'], function(myApp){ ... });を複数回呼び出すと、app/myAppが1回実行されます。したがって、そのような呼び出しは2つとも同じオブジェクトを与えます。別のIDを持つ別個のオブジェクトとして扱うと、動作しません。もちろん、それはアプリの代わりに、アプリ自体のコンストラクタを返すようにスクリプトを変更app/myApp

require(['app/myApp'], function(MyApp){ 
    var myApp = new MyApp(); 
    myApp.init(theId); 
}); 

と:あなたが別のオブジェクトをしたい場合は、このような何かを行います。

+0

ここに表示されているコードはOPのコードと同じ問題があります: 'myApp.init(theId)'は 'theId'と同じ値で2回呼び出されます。 – Louis

+0

@ルイスOPがどのようにしてコードを2度呼び出すのかはわかりません。彼らはもちろん、それを行うことができ、毎回異なるIDで呼び出すことができます。私は一度だけそれを呼んだので、それは私の問題ではありません。要は、毎回新しいオブジェクトを作成する必要があるため、遅延ロードによって提供されるオブジェクトを単純に使用することはできません。 –

関連する問題