コンポーネントの動的な作成
構文は次のとおりです。
1$A.createComponent(String type, Object attributes, function callback)- type — 作成するコンポーネントの種類 ("ui:button" など)。
- attributes — コンポーネントの属性の対応付け。ローカル ID (aura:id) を含みます。
-
callback(cmp, status, errorMessage) — コンポーネントの作成後に呼び出すコールバック。コールバックには 3 つのパラメータがあります。
- cmp — 作成されたコンポーネント。このパラメータを作成するコンポーネントのボディへの追加など、新しいコンポーネントによって何らかの動作を実行することができます。エラーが生じた場合は、cmp が null になります。
- status — コールの状況。有効な値は、SUCCESS、INCOMPLETE、ERROR です。コンポーネントを使用する前に必ず状況が SUCCESS であることを確認します。
- errorMessage — 状況が ERROR の場合のエラーメッセージ。
動的に作成されたボタンを次のサンプルコンポーネントに追加してみましょう。
1<!--c:createComponent-->
2<aura:component>
3 <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
4
5 <p>Dynamically created button</p>
6 {!v.body}
7</aura:component>クライアント側のコントローラは $A.createComponent() をコールして、ローカル ID と press イベントのハンドラが設定された ui:button を作成します。function(newButton, ...) コールバックによって、c:createComponent の body にボタンが追加されます。$A.createComponent() によって動的に作成された newButton は、1 つ目の引数としてコールバックに渡されます。
1/*createComponentController.js*/
2({
3 doInit : function(cmp) {
4 $A.createComponent(
5 "lightning:button",
6 {
7 "aura:id": "findableAuraId",
8 "label": "Press Me",
9 "onclick": cmp.getReference("c.handlePress")
10 },
11 function(newButton, status, errorMessage){
12 //Add the new button to the body array
13 if (status === "SUCCESS") {
14 var body = cmp.get("v.body");
15 body.push(newButton);
16 cmp.set("v.body", body);
17 }
18 else if (status === "INCOMPLETE") {
19 console.log("No response from server or client is offline.")
20 // Show offline error
21 }
22 else if (status === "ERROR") {
23 console.log("Error: " + errorMessage);
24 // Show error message
25 }
26 }
27 );
28 },
29
30 handlePress : function(cmp) {
31 console.log("button pressed");
32 }
33})ネストしたコンポーネントの作成
別のコンポーネントのボディにコンポーネントを動的に作成するには、$A.createComponents() を使用してコンポーネントを作成します。関数コールバックで、外部コンポーネントの body に内部コンポーネントを設定して、コンポーネントをネストします。次の例では、ui:message コンポーネントの body に ui:outputText コンポーネントを作成します。
1$A.createComponents([
2 ["ui:message",{
3 "title" : "Sample Thrown Error",
4 "severity" : "error",
5 }],
6 ["ui:outputText",{
7 "value" : e.message
8 }]
9 ],
10 function(components, status, errorMessage){
11 if (status === "SUCCESS") {
12 var message = components[0];
13 var outputText = components[1];
14 // set the body of the ui:message to be the ui:outputText
15 message.set("v.body", outputText);
16 }
17 else if (status === "INCOMPLETE") {
18 console.log("No response from server or client is offline.")
19 // Show offline error
20 }
21 else if (status === "ERROR") {
22 console.log("Error: " + errorMessage);
23 // Show error message
24 }
25 }
26);動的に作成されたコンポーネントの廃棄
マークアップで宣言されたコンポーネントが使用されなくなると、フレームワークで自動的に廃棄され、メモリが解放されます。
コンポーネントが JavaScript で動的に作成され、そのコンポーネントがファセット (v.body または Aura.Component[] 種別の他の属性) に追加されていない場合は、メモリリークを回避するために、Component.destroy() を使用して手動で廃棄する必要があります。
サーバとの往復の回避
createComponent() メソッドおよび createComponents() メソッドでは、クライアント側のコンポーネントの作成とサーバ側のコンポーネントの作成の両方がサポートされています。パフォーマンス上やその他の理由により、クライアント側の作成をお勧めします。サーバ側の連動関係が見つからない場合、メソッドはクライアント側で実行されます。コンポーネントの作成にサーバ要求が必要かどうかは、最上位コンポーネントで判別されます。
このフレームワークでは、マークアップで定義されたコンポーネントなどの定義間の連動関係が自動的に追跡されます。これらの連動関係は、コンポーネントと共に読み込まれます。ただし、フレームワークで簡単に検出できない連動関係もあります。たとえば、コンポーネントのマークアップで直接参照されていないコンポーネントを動的に作成する場合などがこれに該当します。こうした動的な連動関係をフレームワークが把握できるようにするには、<aura:dependency> タグを使用します。この宣言により、コンポーネントとその連動関係がクライアントに送信されます。
createComponent() または createComponents() への単一のコールによって、多数のコンポーネントが作成される可能性があります。このコールでは、要求されたコンポーネントとそのすべての子コンポーネントが作成されます。パフォーマンス上の考慮事項に加えて、サーバ側のコンポーネント作成には、1 つの要求で作成可能なコンポーネント数が 10,000 個という制限があります。この制限に達する場合は、代わりにクライアント側でコンポーネントが作���されるように、<aura:dependency> タグでコンポーネントの連動関係を明示的に宣言するか、連動要素を事前に読み込みます。
クライアント側でのコンポーネント作成には制限はありません。