LWCの話題にかこつけて、すっかり忘れてたアイツ(Aura component)の話をする
※この記事はSalesforce 開発者向けブログ投稿キャンペーンへのエントリー記事です。
皆様こんにちは。親方です。
みんな、LWC書いてますかー!!!?
ぼくは、Visualforce書いてまーす!
だってClassicサポートしないといけないんだもん
去る6/25にTrailheaDX2020が開催されましたね!
午前0時過ぎから約6時間のナイトパーティーとはなんと粋なスケジュールだったことか(彼らは朝~昼の感覚です)
けど6/28現在、メンテで録画コンテンツが見れん!!!!?
これでは記事が書けん・・・
・・・てなわけで、あんま関係ないこと書きます。
Auraコンポーネントのこと、覚えてますか?
Lightning ExperienceのDev向け目玉コンテンツであったLightningコンポーネント、そのプログラミング基盤として「Aura」が採用されておりました。
これが主流になるから、という触れ込みだったのと上級Dev資格取得に必要だったのでTrailheadでコツコツ勉強しました。その頃にLEX開発やってた案件ではこれ使ったコンポーネントも作りましたよ。
今でもオープンソースだよ!停止してるけど
リファレンスはこちら
そして2018年、Auraはおわりました。
Lightning Web Component(LWC)の登場によって、Auraはレガシーとなり、基盤のリポジトリも止まり、成長が止まりました。
けれども完全に息の根が止まったわけではありません。
コンポーネントライブラリには今でもAura向けのコンポーネントの掲載がありますし、跡形もなく消えたSコンと違って最新環境でもビルドできます。
今回の記事は、そんな中途半端な時期にLightningコンポーネントを修得・実装していたAuraバトラー達の鎮魂のためになればと思い記述したものです。
昔こんなの作ってた
去年のLightning Championの活動の一環として、なんかサンプルコード書かねば・・・という危機感から作ったコードがあります。
カスタムJavascriptボタンがClassicでしか使えないため、Lightning Experience環境で代替できるものを作った感じです。
Aura1:①Contact新規作成アクション(<force:recordData>を使った初期値登録)
Aura2:②Account・Contact一括コピーアクション(Apexコントローラで一括取得・登録)
画面
<aura:component implements="force:hasRecordId,force:lightningQuickAction" access="global" > <aura:handler name="render" value="this" action="{!c.doInit}"/> <aura:attribute name="rec" type="Object"/> <aura:attribute name="recordInfo" type="Object"/> <aura:attribute name="recordId" type="String" /> <aura:attribute name="recordLoadError" type="String"/> <!-- 起動時にレコード情報を読み込み --> <force:recordData aura:id="recordLoader" recordId="{!v.recordId}" fields="Name,Phone,Description,BillingCity,BillingStreet,BillingState,BillingPostalCode,BillingCountry" targetFields="{!v.rec}" targetError="{!v.recordLoadError}" /> </aura:component>
コントローラ
({ //新規作成画面を呼び出し、force:recordDataで受信したレコード情報を初期値として差し込んで表示 doInit : function(component, event, helper) { var createRecordEvent = $A.get("e.force:createRecord"); /* 新規作成画面にパラメータを設定 * entityApiName:対象オブジェクト * defaultFieldValues:初期値を差し込む項目 */ createRecordEvent.setParams({ "entityApiName": "Contact", "defaultFieldValues":{ "Phone":component.get("v.rec.Phone"), "Email":"test@testcompany.co.jp", "Description":component.get("v.rec.Description"), "MailingStreet":component.get("v.rec.BillingStreet"), "MailingCity":component.get("v.rec.BillingCity"), "MailingState":component.get("v.rec.BillingState"), "MailingPostalCode":component.get("v.rec.BillingPostalCode"), "MailingCountry":component.get("v.rec.BillingCountry"), "AccountId":component.get("v.recordId") } }); //新規作成画面を表示 createRecordEvent.fire(); } })
これをLWCで書くと
ちょうど良いサンプルコードとして、これをLWCに移植することを試みました。
以下の点に気をつけながら移植していきます。
- この対応表に準拠し置き換える コンポーネントバンドルのファイルの移行
- Auraでは分けていたJSのControllerとHelperは、LWCでは一つにまとめる
-
lightning系コンポーネントはLWCでもだいたいそのまま使える 基本コンポーネント: Aura コンポーネントと Lightning Web コンポーネント
- その他のUI系マークアップはlightningに置き換えるか、プレーンHTMLに
- <force:recordData>は使えないのでワイヤサービスでデータ取得するよう修正
- データ取得の仕様の違いはこれがわかりやすい Salesforce データの操作 単元 | Salesforce Trailhead
画面
<template> <!-- 起動時にレコード情報を読み込み --> <div class="slds-p-top_large"> <lightning-record-edit-form object-api-name={objectApiName}> <lightning-messages> </lightning-messages> <lightning-input-field field-name="AccountId"> </lightning-input-field> <lightning-input-field field-name="Name"> </lightning-input-field> <lightning-input-field field-name="Phone"> </lightning-input-field> <lightning-input-field field-name="Description"> </lightning-input-field> <lightning-input-field field-name="MailingStreet"> </lightning-input-field> <lightning-input-field field-name="MailingCity"> </lightning-input-field> <lightning-input-field field-name="MailingState"> </lightning-input-field> <lightning-input-field field-name="MailingPostalCode"> </lightning-input-field> <lightning-input-field field-name="MailingCountry"> </lightning-input-field> <lightning-button class="slds-m-top_small" type="submit" label="新規作成"> </lightning-button> </lightning-record-edit-form> </div> </template>
コントローラ
import { LightningElement, api, wire } from 'lwc'; import { getRecord, getFieldValue } from 'lightning/uiRecordApi'; import CONTACT_OBJECT from '@salesforce/schema/Contact'; const FIELDS = [ 'Account.Id', 'Account.Name', 'Account.Phone', 'Account.Description', 'Account.BillingCity', 'Account.BillingStreet', 'Account.BillingState', 'Account.BillingPostalCode', 'Account.BillingCountry', ]; export default class LwcComp1 extends LightningElement { @api recordId; objectApiName = CONTACT_OBJECT; @wire(getRecord, { recordId: '$recordId', fields: FIELDS }) wiredRecord({ error, data }) { if (data) { console.log('success'); console.log(data); this.AccountId = getFieldValue(data, 'Account.Id'); this.Phone = getFieldValue(data, 'Account.Phone'); this.Description = getFieldValue(data, 'Account.Description'); this.MailingStreet = getFieldValue(data, 'Account.BillingStreet'); this.MailingCity = getFieldValue(data, 'Account.BillingCity'); this.MailingState = getFieldValue(data, 'Account.BillingState'); this.MailingPostalCode = getFieldValue(data, 'Account.BillingPostalCode'); this.MailingCountry = getFieldValue(data, 'Account.BillingCountry'); } else if (error) { // Handle error. Details in error.message. console.log('error'); console.log(error); } } }
基本方針はわかった。しかし・・・
基本的に、AuraでできることはだいたいLWCでできます。
しかし、現行LWCの仕様ではできないことがあります。
Lightningレコードページから呼び出すアクションに指定できないんです。
今見たらやっぱりAuraで作ることになってました
これ今でもできないんでしたっけ・・・?
Lightning アクションは、既存の Lightning コンポーネントフレームワーク上に構築されます。既存の Aura コンポーネントを簡単にアクションに変換して、Salesforce モバイルアプリケーションや Lightning Experience で使用することができます。
Aura コンポーネントをアクションとして起動可能にするために、force:lightningQuickAction と force:lightningQuickActionWithoutHeader のいずれかのインターフェースをコンポーネントに追加します。
上述したforce:recordDataと同様に、force:XXXインターフェースはLWCには存在しないんです。
LWC時代にはどうやって作ればよいのでしょうか。
色々考えてみた
Auraコンポーネントの中にLWCを入れる
実は、AuraコンポーネントとLWCは入れ子構造にすることができます。
(常にAura側が親となる)
Lightning Web コンポーネントからの Aura コンポーネントの作成
一旦LWCを作った後、外枠としてAuraコンポーネントを作成し、そこにLWCを差し込むことでほぼLWCなAuraコンポーネントを作成することができます。
<aura:component implements="force:hasRecordId,force:lightningQuickAction"> <c:lwcActionDetail name="LWC" /> </aura:component>
- メリット:ほぼLWCで作れる
- デメリット:形式上Auraは残る
Lightningフローを使う
Lightningコンポーネントと同様に、画面フローもまたアクションから呼び出すことができます。
(グローバルアクションを除く)
フローをうまく使えば数百件クラスの一括データ操作も可能ですし、いっそノンコーディングに置き換えるのも選択肢かと思います。
またTrailheaDXネタですが、Javascrpitを動かしたいのであれば"Salesforce Functions"も選択肢に含まれます。Salesforce Functionsはフローの中からサーバサイド処理として呼び出せるため、Lightningコンポーネントのコントローラを移植することができるのではないのでしょうか。
- メリット:ノンコーディング開発できる
- デメリット:UIの拡張性は今一つ、サーバサイド処理になる
Visualforceを使う
ええと、Lightning Championの立場からしたらお勧めしかねるのですが、ある意味最も堅実な選択肢です。
だってこれClassicでも動くんだもの!!
UIコンポーネントが充実しているLWCと異なり陳腐化したApexマークアップしか使えないVisualforceではありますが、自分でJavascriptフレームワークを導入すれば大した問題ではありません。
マークアップを極力使わず、Javascript主体で処理を行いApexもRemoteActionから呼ぶようにすればLightningコンポーネントと遜色ない処理はできてしまいます。
上のサンプルコードでも、Auraコンポーネント部分をVFに挿げ替えられるように作ってました。Apexクラスは簡単に共有化できますよ!
- メリット:なんだかんだ好きに書けるので潰しが効く
- デメリット:あるか?(Classic使わない人は覚えないでいいのでは)
あとがき
・・・てな感じで、画面作成のプラットフォームとしてはLWCが最先端で、Visualforceが根強く残り、Auraはその狭間でレガシーとして細々と存在している状態です。
今更習得するメリットは正直ほとんどないのですが、与太話として思い出して頂ければ幸いです。
さて、LWCの勉強せねば・・・