この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

レコード固有のアクションのコンポーネントの設定

force:hasRecordId インターフェースを Lightning コンポーネントに追加して、現在表示されているレコードの ID をコンポーネントに割り当てることができるようにします。現在のレコード ID は、コンポーネントが Lightning Experience または Salesforce1 のオブジェクト固有のカスタムアクションとして使用されている場合に便利です。
force:hasRecordId インターフェースは、このインターフェースを実装するコンポーネントに対して 2 つのことを行います。
  • recordId という名前の属性をコンポーネントに追加します。この属性は文字列型であり、その値は 18 文字の Salesforce レコード ID (001xx000003DGSWAA4 など) です。これを自分で追加した場合、属性の定義は次のようになります。
    1<aura:attribute name="recordId" type="String" />

    force:hasRecordId を実装する場合、recordId 属性をコンポーネントに自分で追加する必要はありません。追加する場合は、属性のアクセスレベルまたは型を変更しないでください。変更すると、コンポーネントでランタイムエラーが発生します。

    メモ

  • Lightning Experience または Salesforce1 のレコードコンテキストでコンポーネントを呼び出す場合、recordId を、表示するレコードの ID に設定します。
この動作は、プログラミング言語のインターフェースで予想される動作とは異なります。これは、force:hasRecordIdマーカーインターフェースであるためです。マーカーインターフェースは、インターフェースの動作をコンポーネントに追加するよう伝える、コンポーネン���のコンテナへの信号です。

レコードページにコンポーネントを配置する場合、またはレコードページからコンポーネントをアクションとして呼び出す場合のみ、レコード ID が設定されます。その他の場合 (このコンポーネントをプログラムで別のコンポーネント内に作成する場合など)、レコード ID は設定されないため、コンポーネントでレコード ID を使用しないでください。

レコード固有のアクションのコンポーネントの例

この拡張の例では、取引先レコードの詳細ページからカスタムアクションとして呼び出されるように設計されたコンポーネントを示します。コンポーネントを作成したら、取引先オブジェクトのカスタムアクションを作成し、取引先ページレイアウトに追加する必要があります。アクションを使用した開かれたコンポーネントは、次のようなアクションパネルに表示されます。QuickContact アクションパネル

コンポーネント定義は、まず force:lightningQuickActionWithoutHeaderforce:hasRecordId の両方のインターフェースで実装されます。最初のインターフェースは、コンポーネントをアクションとして使用できるようにし、標準コントロールが表示されないようにします。2 番目のインターフェースは、レコードのコンテキストでコンポーネントが呼び出されたときにインターフェースのレコード ID 属性と値の自動割り当て動作を追加します。

quickContact.cmp
1<aura:component controller="QuickContactController"
2    implements="force:lightningQuickActionWithoutHeader,force:hasRecordId">
3
4    <aura:attribute name="account" type="Account" />
5    <aura:attribute name="newContact" type="Contact"
6        default="{ 'sobjectType': 'Contact' }" /> <!-- default to empty record -->
7    <aura:attribute name="hasErrors" type="Boolean"
8        description="Indicate if there were failures when validating the contact." />
9
10    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
11
12    <!-- Display a header with details about the account -->
13    <div class="slds-page-header" role="banner">
14        <p class="slds-text-heading--label">{!v.account.Name}</p>
15        <h1 class="slds-page-header__title slds-m-right--small
16            slds-truncate slds-align-left">Create New Contact</h1>
17    </div>
18
19    <!-- Display form validation errors, if any -->
20    <aura:if isTrue="{!v.hasErrors}">
21        <div class="recordSaveError">
22            <ui:message title="Error" severity="error" closable="true">
23                The new contact can't be saved because it's not valid.
24                Please review and correct the errors in the form.
25            </ui:message>
26        </div>
27    </aura:if>
28
29    <!-- Display the new contact form -->
30    <div class="slds-form--stacked">
31
32        <div class="slds-form-element">
33            <label class="slds-form-element__label" 
34                for="contactFirstName">First Name: </label>
35            <div class="slds-form-element__control">
36              <ui:inputText class="slds-input" aura:id="contactFirstName"
37                value="{!v.newContact.FirstName}" required="true"/>
38            </div>
39        </div>
40        <div class="slds-form-element">
41            <label class="slds-form-element__label" 
42                for="contactLastName">Last Name: </label>
43            <div class="slds-form-element__control">
44              <ui:inputText class="slds-input" aura:id="contactLastName"
45                value="{!v.newContact.LastName}" required="true"/>
46            </div>
47        </div>
48
49        <div class="slds-form-element">
50            <label class="slds-form-element__label" for="contactTitle">Title: </label>
51            <div class="slds-form-element__control">
52              <ui:inputText class="slds-input" aura:id="contactTitle"
53                value="{!v.newContact.Title}" />
54            </div>
55        </div>
56
57        <div class="slds-form-element">
58            <label class="slds-form-element__label" 
59                for="contactPhone">Phone Number: </label>
60            <div class="slds-form-element__control">
61              <ui:inputPhone class="slds-input" aura:id="contactPhone"
62                value="{!v.newContact.Phone}" required="true"/>
63            </div>
64        </div>
65        <div class="slds-form-element">
66            <label class="slds-form-element__label" for="contactEmail">Email: </label>
67            <div class="slds-form-element__control">
68              <ui:inputEmail class="slds-input" aura:id="contactEmail"
69                value="{!v.newContact.Email}" />
70            </div>
71        </div>
72
73        <div class="slds-form-element">
74            <ui:button label="Cancel" press="{!c.handleCancel}"
75                class="slds-button slds-button--neutral" />
76            <ui:button label="Save Contact" press="{!c.handleSaveContact}"
77                class="slds-button slds-button--brand" />
78        </div>
79
80    </div>
81
82</aura:component>
コンポーネントでは、メンバー変数として使用される 3 つの属性が定義されます。
  • account — init ハンドラで読み込まれた完全な取引先レコードを保持
  • newContact — フォーム項目の値を取得するために使用される空の取引先責任者
  • hasErrors — フォームの入力規則エラーが発生したかどうかを示す Boolean フラグ
残りのコンポーネント定義は、スタイル設定に Lightning Design System を使用する標準フォームです。

コンポーネントのコントローラには、3 つのアクションハンドラの目的のすべてのコードがあります。

quickContactController.js
1({
2    doInit : function(component, event, helper) {
3
4        // Prepare the action to load account record
5        var action = component.get("c.getAccount");
6        action.setParams({"accountId": component.get("v.recordId")});
7
8        // Configure response handler
9        action.setCallback(this, function(response) {
10            var state = response.getState();
11            if(component.isValid() && state === "SUCCESS") {
12                component.set("v.account", response.getReturnValue());
13            } else {
14                console.log('Problem getting account, response state: ' + state);
15            }
16        });
17        $A.enqueueAction(action);
18    },
19
20    handleSaveContact: function(component, event, helper) {
21        if(helper.validateContactForm(component)) {
22            component.set("v.hasErrors", false);
23
24            // Prepare the action to create the new contact
25            var saveContactAction = component.get("c.saveContactWithAccount");
26            saveContactAction.setParams({
27                "contact": component.get("v.newContact"),
28                "accountId": component.get("v.recordId")
29            });
30
31            // Configure the response handler for the action
32            saveContactAction.setCallback(this, function(response) {
33                var state = response.getState();
34                if(component.isValid() && state === "SUCCESS") {
35
36                    // Prepare a toast UI message
37                    var resultsToast = $A.get("e.force:showToast");
38                    resultsToast.setParams({
39                        "title": "Contact Saved",
40                        "message": "The new contact was created."
41                    });
42
43                    // Update the UI: close panel, show toast, refresh account page
44                    $A.get("e.force:closeQuickAction").fire();
45                    resultsToast.fire();
46                    $A.get("e.force:refreshView").fire();
47                }
48                else if (state === "ERROR") {
49                    console.log('Problem saving contact, response state: ' + state);
50                }
51                else {
52                    console.log('Unknown problem, response state: ' + state);
53                }
54            });
55
56            // Send the request to create the new contact
57            $A.enqueueAction(saveContactAction);
58        }
59        else {
60            // New contact form failed validation, show a message to review errors
61            component.set("v.hasErrors", true);
62        }
63    },
64
65	handleCancel: function(component, event, helper) {
66	    $A.get("e.force:closeQuickAction").fire();
67    }
68})

最初のアクションハンドラ doInit は init ハンドラです。このハンドラのジョブは、force:hasRecordId インターフェースで提供されるレコード ID を使用して、完全な取引先レコードを読み込むことです。このコンポーネントが別のオブジェクト (リード、商談、またはカスタムオブジェクト) のアクションで使用されないようにする手段は講じられていません。この場合、doInit ではレコードの読み込みに失敗しますが、フォームは表示されます。

handleSaveContact アクションハンドラは、ヘルパー関数をコールしてフォームを検証します。フォームが無効であった場合、アクションハンドラはフォームエラーメッセージを表示するフラグを設定します。フォームが有効であった場合、アクションハンドラは次の作業を行います。
  • 新しい取引先責任者を保存するサーバアクションを準備をする。
  • サーバがアクションを完了したときのためにレスポンスハンドラと呼ばれるコールバック関数を定義する。レスポンスハンドラについては、後ほど説明します。
  • サーバアクションをキューに追加する。
サーバアクションのレスポンスハンドラ自体はほとんど作業をしません。サーバアクションが成功すると、レスポンスハンドラは次の作業を行います。
  • force:closeQuickAction イベントを起動してアクションパネルを閉じる。
  • force:showToast イベントを起動して、取引先責任者が作成されたことを示す「トースト」メッセージを表示する。
  • レコードページに自身を更新するように通知する force:refreshView イベントを起動して、レコードページを更新する。
更新イベントに対応して取引先責任者のリストが更新されると、リストの最後の項目に新しいレコードが表示されます。

handleCancel アクションハンドラは、force:closeQuickAction イベントを起動してアクションパネルを閉じます。

ここに記載されているコンポーネントヘルパーは、その用途を十分に説明できるだけの最小限のヘルパーです。本番品質のフォーム検証コードでは、さらに多くの作業が必要になります。

quickContactHelper.js
1({
2	validateContactForm: function(component) {
3        var validContact = true;
4
5        // First and Last Name are required
6        var firstNameField = component.find("contactFirstName");
7        if($A.util.isEmpty(firstNameField.get("v.value"))) {
8            validContact = false;
9            firstNameField.set("v.errors", [{message:"First name can't be blank"}]);
10        }
11        else {
12            firstNameField.set("v.errors", null);
13        }
14        var lastNameField = component.find("contactLastName");
15        if($A.util.isEmpty(lastNameField.get("v.value"))) {
16            validContact = false;
17            lastNameField.set("v.errors", [{message:"Last name can't be blank"}]);
18        }
19        else {
20            lastNameField.set("v.errors", null);
21        }
22
23        // Verify we have an account to attach it to
24        var account = component.get("v.account");
25        if($A.util.isEmpty(account)) {
26            validContact = false;
27            console.log("Quick action context doesn't have a valid account.");
28        }
29
30        // TODO: (Maybe) Validate email and phone number
31
32        return(validContact);
33	}
34})

最後に、このコンポーネントのサーバ側コントローラとして使用される Apex クラスは、わかりやすいように意図的に簡略化されています。

QuickContactController.apxc
1public with sharing class QuickContactController {
2
3    @AuraEnabled
4    public static Account getAccount(Id accountId) {
5        // Perform isAccessible() checks here
6        return [SELECT Name, BillingCity, BillingState FROM Account WHERE Id = :accountId];
7    }
8    
9    @AuraEnabled
10    public static Contact saveContactWithAccount(Contact contact, Id accountId) {
11        // Perform isAccessible() and isUpdateable() checks here
12        contact.AccountId = accountId;
13        upsert contact;
14        return contact;
15    }
16
17}
一方のメソッドは、レコード ID に基づいて取引先を取得します。他方のメソッドは、新規取引先責任者レコードを取引先に割り当て、データベースに保存します。