コンポーネントの動的な作成
構文は次のとおりです。
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> タグを使用します。これにより、必要に応じてコンポーネントとその連動関係がクライアントに送信されます。
コンポーネントの作成にサーバ要求が必要かどうかは、最上位コンポーネントで判別されます。