Posted at

コンポーネントの動的生成によるui:messageのラッパー

More than 3 years have passed since last update.

ドキュメントに、$A.componentService.newComponentAsyncを使ってui:messageを動的に作るサンプルが記載されていました。

しかし、そのまま書いたら恒例の内部エラーが出力されてしまいました。

コンポーネントの入れ子生成ができないようです。

下記のようにタイトルだけ出力させるようにしたら動作しました。


SimpleSample.app

<aura:application>

<tiwasakidemo:TitleOnlyMessage />
</aura:application>


TitleOnlyMessage.cmp

<aura:component>   

<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

<div aura:id="placeholder">value to be replaced.</div>
</aura:component>



TitleOnlyMessage.js

({

doInit : function(component, event, helper) {
var def = {
componentDef: 'markup://ui:message',
attributes : {
values : {
title : 'hello'
}
}
};
$A.componentService.newComponentAsync(
this,
function(message) {
var placeholder = component.find('placeholder');
placeholder.set('v.body', message);
},
def
);
}
})

しかし、同等の記述をタグで記述するとなぜか保存時にエラーになってしまいます。


.cmp

    <ui:message title="hello">v.body</ui:message>

<ui:message title="hello"></ui:message>

v.bodyComponent[]型の取り扱いが鬼門のようです。

取り急ぎ、ドキュメントにあるサンプルと同じく文字列型で動作するようにしてみましょう。

コンポーネントの入れ子生成ができないならば、1つずつ作成すれば良いですね。

引数はui:messageのソースからいただいてきました。


message.cmp

<aura:component>   

<aura:attribute name="message" type="String" />
<aura:attribute access="GLOBAL" name="title" type="String" description="The title text for the message."/>
<aura:attribute access="GLOBAL" name="severity" type="String" default="message" description="The severity of the message. Possible values: message (default), confirm, info, warning, error"/>
<aura:attribute access="GLOBAL" name="closable" type="Boolean" default="false" description="Specifies whether to display an 'x' that will close the alert when clicked. Default value is 'false'."/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

<div aura:id="placeholder"></div>
</aura:component>



messageController.js

({

doInit : function(component, event, helper) {
var title = component.get('v.title');
var message = component.get('v.message');
var severity = component.get('v.severity') || 'message';
var closable = component.get('v.closable') || false;
if ($A.util.isUndefinedOrNull(message) && $A.util.isUndefinedOrNull(title))
message = severity;

var defUiMessage = {
componentDef : 'markup://ui:message',
attributes : {
values : {
title : title,
severity : severity,
closable : closable
}
}
};
var defUiOutputText = {
componentDef : 'markup://ui:outputText',
attributes : {
values : {
value : message
}
}
};

var that = this;
$A.componentService.newComponentAsync(
this,
function(uiMessage) {
$A.componentService.newComponentAsync(
that,
function(uiOutputText) {
if (!$A.util.isUndefinedOrNull(message))
uiMessage.set('v.body', uiOutputText);
var placeholder = component.find('placeholder');
placeholder.set('v.body', uiMessage);
},
defUiOutputText
);
},
defUiMessage
);
}
})


こんな風に書くと


sample.app

<aura:application>

<tiwasakidemo:message severity="message" title="hello" message="world" closable="true" />
<tiwasakidemo:message severity="confirm" title="hello" message="world" closable="true" />
<tiwasakidemo:message severity="debug" title="hello" message="world" closable="true" />
<tiwasakidemo:message severity="info" title="hello" message="world" closable="true" />
<tiwasakidemo:message severity="warning" title="hello" message="world" closable="true" />
<tiwasakidemo:message severity="error" title="hello" message="world" closable="true" />
</aura:application>

こうなります。

スクリーンショット 2014-12-18 12.40.26.png

これらのスタイルはuiMessageクラス、.uiMessgae.errorセレクターなどに対して設定されていますので、適宜cssにて上書きすることもできます。

それぞれのパラメーターは省略もできるようになっていますので指定を色々変えて試してみてください。

さらっと書きましたがJavaScript書き慣れていない方はカンマや括弧の位置、クロージャーなどの記述にご注意ください。