まとめ:aura:id
がexpenseform
の<lightning:input>
タグをすべて検証して、1件でも不正な入力があったらエラーメッセージを表示します。
({
clickCreate: function(component, event, helper) {
var validExpense = component.find('expenseform').reduce(function (validSoFar, inputCmp) {
// Displays error messages for invalid fields
inputCmp.showHelpMessageIfInvalid();
return validSoFar && inputCmp.get('v.validity').valid;
}, true);
// If we pass error checking, do some real work
if(validExpense){
// Create the new expense
var newExpense = component.get("v.newExpense");
console.log("Create expense: " + JSON.stringify(newExpense));
helper.createExpense(component, newExpense);
}
}
})
チャレンジでもなんでもない中盤に出てくるコントローラですが、前半(if分の手前)がぱっと見で理解できず手が止まったので詳しく記録します。
海外にも同じ悩みを持った方がそこそこいた模様(リンク)。
reduceメソッド
Qiitaの評価されている記事によると、
隣り合う2つの配列要素に対して左から右へ同時に関数を適用し、単一の値にする。というメソッドです。
例えば、「配列の中身を一つずつ足していって合計を求める」ということができます。
構文:array.reduce(callback [, initialValue])
- array:
component.find('expenseform')
- previous:一つ前の要素またはinitialValue。今回は
validSoFar
にこの値が入っている。 - current:現在処理されている要素。今回は
inputCmp
にこの値が入っている。 - index:現在処理されている要素のインデックス。
- initialValue:省略可能の第二引数の値。今回は'true'が入っている。
component.find('expenseform')
はaura:id
がexpenseform
の<lightning:input>
タグへの参照を配列で取得できます。今回はすべての<lightning:input>
タグにidが設定されています。
showHelpMessageIfInvalid()
公式の文書のSpecificationを見てみましょう。メソッドが5つあります。
<lightning:input>
が標準で有するメソッドにこれが記述されています。フォームコントロールが無効な状態にある場合にヘルプメッセージを表示します。
inputCmp.get('v.validity').valid
コンポーネントに含まれている「validity」属性を取得し、さらにこれに含まれる「valid」プロパティを取得しています。公式によれば、このプロパティはBoolean型です。入力値に問題がないときのもTrueになります。
valid: True if none of the preceding properties are true.
return validSoFar && inputCmp.get('v.validity').valid;
returnする値は、数値ではなくBooleanです。リンク元では、previousとcurrentの加算値を返していました。
今回は、validSoFar
(previous)とinputCmp.get('v.validity').valid
(current)が共にTrueのときにTrueを返し、currentがfalseのとき(入力値に不正があったとき)にfalseを返します。
これを繰り返すということはつまり、ひとつでも不正な入力を検知したら後のループすべてがfalseになるということです。
reduceメソッドは合計を求めるのではなく、falseが1度でも存在したかどうか確認するために用いていたのです。
showHelpMessageIfInvalid()は、これを通しさえすれば赤文字エラーメッセージが表示されるということです。