Salesforce學習之路-developer篇(五)一文讀懂Aura原理及實戰案例分析
- 2019 年 11 月 13 日
- 筆記
很喜歡曾經看到的一句話:以輸出倒逼輸入。以輸出的形式強制自己學習,確實是高效的學習方式,真的很棒。以下僅為個人學習理解,如有錯誤,歡迎指出,共同學習。
1. 什麼是Lightning Component框架?
Lightning Component框架是一個UI框架,用於為移動和台式設備開發Web應用程式。這是一個單頁面Web應用框架,用於為Lightning Platform應用程式構建具有動態,響應式用戶介面的單頁應用程式。它在客戶端使用JavaScript,在伺服器端使用Apex。
Lightning Component作為Web應用框架,可以輕鬆的創建自定義應用程式,而不必自己編寫全部程式碼。常用的Web應用程式框架有很多, 例如:Ruby on Rails, Grails, AngularJS, Django, CakePHP等等,甚至前面提到的Visualforc component也是一種web框架。
當然,Lighnting Component也可以看成是CS架構。
客戶端主要由兩個元素組成:View和Controller
- View:是XML markup,同時混合了自定義的Aura component靜態HTML標籤,例如:<aura:component>標籤。如果有過Visualforce經驗的小夥伴一定對該格式比較熟悉:namespace:tagName。對於Aura的組件,Salesforce提供了非常完善的參考,各種不同的組件都已經給出參考示例,大大減少了開發和學習成本。具體的地址:https://developer.salesforce.com/docs/component-library/overview/components
- Controller:主要是由JavaScript語言編寫,其目的主要是和服務端進行綁定,獲取所需的數據,並提供給View進行展示。
服務端主要也有兩個元素組成:Controller和Database。
- Controller: 由Apex語言開發(類似於Java語言),Apex與Java一樣,由一個個類文件組成,不同的是Java為.java文件,而Apex為.cls文件。注意,在客戶端的View文件中綁定的是類名稱。
- Database: 使用數據操作語言DML(Data Manipulation Language)對數據進行插入,更新,刪除和創建操作。
2. Aura組件捆綁包
Aura組件便是基於Lighnting Component框架進行的二次開發。
2.1 組件的命名規則
創建組件時,其命名的規則必須滿足如下條件:
- 必須以字母開頭
- 必須僅包含字母數字或下劃線字元
- 在命名空間中唯一
- 不能包含空格
- 不能以下劃線結尾
- 不能包含兩個連續的下劃線
2.2 組件創建的文件
當我們在工程中創建一個新的Aura捆綁包(以下捆綁包都稱為組件)時,工程會自動創建出.auradoc,.cmp,.xml,.css,.design,svg,controller.js,help.js,renderer.js幾個文件。
資源 | 資源名稱 | 用途 |
component | testAura.cmp | 在捆綁包中唯一的必要資源,包含了組件的標記,並且每個捆綁包中只有一個component。 |
CSS樣式 | testAura.css | 組件的形狀格式 |
Design | testAura.design | 當組件在Lightning App Builder或者Lightning Page中使用時需要用到該文件 |
Helper | testAuraHelper.js | Javascript函數,該函數可以被捆綁包中的任何javascript程式碼調用 |
Documentation | testAura.auradoc | 對組件的一些簡單介紹說明 |
Renderer | testAuraRenderer.js | 客戶端渲染器會覆蓋默認的渲染器 |
Controller | testAuraController.js | 客戶端的控制函數,用來處理組件中的事件 |
SVG文件 | testAura.svg | 組件的自定義圖標資源,一般為Lightning App Builder中使用的圖標 |
組件捆綁包中的所有資源都遵循命名規則,並且自動綁定連接。例如:<aura:component controller=”TestAuraController”>,組件會自動連接TestAuraController.cls類,所以組件內所有資源都可連接該控制類。
2.3 組件的工作原理
組件由自動創建的一系列文件組成,並且每個文件都發揮著不同的功能。其中,組件的主體便是component(.cmp文件),對於最精簡的組件來講,只修改.cmp文件即可(其他文件使用默認值),該文件為組件定義了視圖。
當然,對於實際項目開發中,僅僅含有視圖是遠遠不夠的。通常,我們需要修改controller.js和helper.js文件。controller.js與.cmp文件交互,提供視圖中所需要的數據;helper.js與伺服器controller.cls交互,獲取資料庫中的數據;controller.js直接調用helper.js中的函數(當然,可以把helper.js中的函數直接寫在controller.js中,直接從controller.js中獲取資料庫中的數據,但該模式不便與維護,不推薦使用)。
如果組件需要與伺服器中資料庫進行交互,則還需創建一個Apex控制類,與控制類與資料庫交互,並將數據傳遞給組件。
不同文件之間的聯繫,如下圖所示:
3. 組件的命名空間
3.1 命名空間的適用場景
每個組件都是命名空間的一部分,如果Org中設置了命名空間前綴,那麼需使用該命名空間訪問組件。否則,使用默認命名空間訪問組件,系統默認的命名空間為“c”。
- 如果Org沒有創建命名空間前綴,下述情況必須使用“c”命名空間前綴:
- 引用自定義創建的組件
- 引用自定義創建的事件
- 如果Org沒有創建命名空間,下述情況下Org會自動使用隱式命名空間,即該場景下無需使用指定的命名空間前綴:
- 引用自定義對象
- 引用標準對象和自定義對象的欄位
- 引用Apex的控制類
- 如果Org創建了命名空間前綴,下述情況下必須使用自定義的命名空間前綴:
- 引用自定義創建的組件
- 引用自定義創建的事件
- 引用自定義對象
- 引用標準對象和自定義對象的欄位
- 引用Apex的控制類
- 引用靜態資源
3.2 命名空間命名規則
命名規則必須滿足以下條件:
- 以字母開頭
- 包含1-15個字母數字字元
- 不包含兩個下劃線
例如: myNamespace123和my_namespace是有效的;123MyNamespce和my__namespace是無效的。
3.3 創建命名空間
Setup–>Packages(注意:該條目只在Salesforce Classic版本中才有)–>Developer Settings–>Edit
Check Avaliability校驗名稱是否滿足規則。
3.4 命名空間使用示例
- Org沒有設置命名空間前綴
引用項 | 示例 |
標記中使用組件 | <c:myComponent> |
系統屬性中使用組件 |
<aura:component extends=”c:myComponent”> |
Apex控制類 | <aura:component controller=”ExpenseController“> |
屬性的類型為自定義對象 | <aura:attribute name=”expense” type=”Expense__c” /> |
屬性的類型為自定義對象,並且設置默認值 |
<aura:attribute name="newExpense" type="Expense__c" default="{ 'sobjectType': 'Expense__c', 'Name': '', 'Amount__c': 0, … }" /> |
表達式中含有自定義對象的欄位 | <ui:inputNumber value=“{!v.newExpense.Amount__c}” label=… /> |
javascript函數中含有自定義對象欄位 |
updateTotal: function(component) { … for(var i = 0 ; i < expenses.length ; i++){ var exp = expenses[i]; total += exp.Amount__c; } … } |
在Javascript函數中動態創建新的組件 |
var myCmp = $A.createComponent("c:myComponent", {}, function(myCmp) { } );
|
在Javascript函數中的介面對比 | aCmp.isInstanceOf(“c:myInterface“) |
註冊事件 | <aura:registerEvent type=“c:updateExpenseItem” name=… /> |
事件處理 | <aura:handler event=“c:updateExpenseItem” action=… /> |
顯式依賴 | <aura:dependency resource=”markup://c:myComponent” /> |
Javascript函數中的應用事件 | var updateEvent = $A.get(“e.c:updateExpenseItem“); |
靜態資源 | <ltng:require scripts=“{!$Resource.resourceName}” styles=“{!$Resource.resourceName}” /> |
- Org設置了命名空間前綴
引用項 | 示例 |
標記中使用組件 | <yournamespace:myComponent /> |
系統屬性中使用組件 |
<aura:component extends=”yournamespace:myComponent”> |
Apex控制類 | <aura:component controller=“yournamespace.ExpenseController“> |
屬性的類型為自定義對象 | <aura:attribute name=“expenses” type=“yournamespace__Expense__c[]” /> |
屬性的類型為自定義對象,並且設置默認值 |
<aura:attribute name="newExpense" type="yournamespace__Expense__c" default="{ 'sobjectType': 'yournamespace__Expense__c', 'Name': '', 'yournamespace__Amount__c': 0, … }" /> |
表達式中含有自定義對象的欄位 | <ui:inputNumber value=“{!v.newExpense.yournamespace__Amount__c}” label=… /> |
javascript函數中含有自定義對象欄位 |
updateTotal: function(component) { … for(var i = 0 ; i < expenses.length ; i++){ var exp = expenses[i]; total += exp.yournamespace__Amount__c; } … } |
在Javascript函數中動態創建新的組件 |
var myCmp = $A.createComponent("yournamespace:myComponent", {}, function(myCmp) { } );
|
在Javascript函數中的介面對比 | aCmp.isInstanceOf(“yournamespace:myInterface“) |
註冊事件 | <aura:registerEvent type=“yournamespace:updateExpenseItem” name=… /> |
事件處理 | <aura:handler event=“yournamespace:updateExpenseItem” action=… /> |
顯式依賴 | <aura:dependency resource=”markup://yournamespace:myComponent” /> |
Javascript函數中的應用事件 | var updateEvent = $A.get(“e.yournamespace:updateExpenseItem“); |
靜態資源 | <ltng:require scripts=“{!$Resource.yournamespace__resourceName}” styles=“{!$Resource.yournamespace__resourceName}” /> |
4 組件的主體
4.1 配置項
在創建Aura組件時,可在該文件中配置組件的配置選項。配置選項都是可選的,所以可以進行任意組合。
在Aura組件中提供如下配置項:
配置 | 標記 | 描述 |
Lightning Tab | implements=”force:appHostable” | 創建一個組件,該組件可以作用Lightning Experience或者Salesfroce手機App的導航元素 |
Lightning Page | implements=”flexipage:avaliableForAllPageTypes” and access=”global” | 創建一個組件,該組件可以用在Lightning頁面或者Lightning App Builder中 |
Lighnting Record Page | implements=”flexipage:availableForRecordHome, force:hasRecordId” and access=”global” | 創建一個組件,該組件可以用在Lightning Experience的記錄的Home頁面 |
Lighnting Communities Page |
implements=”forceCommunity:availableForAllPageTypes” and access=”global” |
創建一個組件,該組件支援在Community Builder中拖拽功能 |
Lighnting Quick Action | implements=”force:lightningQuickAction” | 創建一個組件,該組件可以充當一個Lightnging quick action |
示例:
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes"> </aura:component>
4.2 組件屬性
組件屬性類似與Apex中類的成員變數(或者說Java中類的成員變數)。他們是組件在特定的實例上設置的類型化欄位,可以使用表達式語法從組件的標記內引用他們。
語法:<aura:attribute name=”**” type=”**” default=”**” required=”true/false” access=”**” description=”**”>
- name:必要欄位,屬性的名稱
- type:必要欄位,屬性的類型,支援的類型見下面的“屬性type支援的類型”
- default:非必要欄位,默認值類型與type一致。
- required:非必要欄位,標記該屬性是否為必須欄位。true:表該欄位為必要欄位;false:表該欄位為非必要欄位。
- access: 非必要欄位,表該屬性是否可被所屬命名空間之外使用。public(默認):所有命名空間皆可用;global:應用內可使用;private: 組件內可使用。
- description: 非必要欄位,對該屬性進行簡單的描述。
示例:
<aura:component> <aura:attribute name="whom" type="String" default="world"/> Hello {!v.whom}! </aura:component>
1) 屬性命名規則:
- 必須以字母或者下劃線開頭
- 必須僅包含字母數字或者下劃線字元
2) 屬性type支援的類型
aura:attribute支援的類型有以下幾種:基礎類型,函數類型,對象類型,標準和自定義對象類型,集合類型,Apex Class類型,指定框架類型。
- 基礎類型
類型 | 示例 | 描述 |
Boolean | <aura:attribute name=”showDetail” type=”Boolean” /> | 值為true/false |
Date | <aura:attribute name=”startDate” type=”Date” /> | 日期類型,格式為:yyyy-mm-dd。hh:mm:ss沒有保存。 |
DateTime | <aura:attribute name=”lastModifiedDate” type=”DateTime” /> |
日期類型,對應時間戳格式。 保存了除了日期,還保存了時間,並且精確到毫秒。 |
Decimal | <aura:attribute name=”totalPrice” type=”Decimal” /> |
十進位,可以包括小數部分。對應Java.math.BigDecimal,精度高於Double類型。 針對貨幣欄位,一般選擇該類型。 |
Double | <aura:attribute name=”widthInchesFractional” type=”Double” /> | Double類型,可以包含小數位。對應Java.lang.Double。 |
Integer | <aura:attribute name=”numRecords” type=”Integer” /> | 整數類型,不包含小數位。對應Java.lang.Integer。 |
Long | <aura:attribute name=”numSwissBankAccount” type=”Long” /> | 長整型,不包含小數位。對應Java.lang.Long。 |
String | <aura:attribute name=”message” type=”String” /> | 字元串類型。 |
示例:
<aura:attribute name="favoriteColors" type="String[]" default="['red','green','blue']" />
- 函數類型
屬性的類型可以對象Javascript中的某個函數。如果子組件具有該類型的屬性,可傳遞迴調函數給父組件。
示例:
<aura:attribute name="callback" type="Function" />
注意:該類型不適用於服務端,僅在客戶端使用。
- 對象類型
該類型的屬性對應一個對象。
示例:
<aura:attribute name="data" type="Object" />
注意:一般情況下,不建議使用該類型。object類型的屬性在傳遞至服務端時,會將所有的東西序列化為字元串,此時如果使用深度表達(例如:v.data.property),則會拋出字元串沒有該屬性異常。因此,盡量使用type=”Map”,防止出現反序列化等問題。
- 標準或自定義對象類型
屬性支援標準或自定義對象的類型。
示例:
<aura:attribute name="acct" type="Account" /> <aura:attribute name="expense" type="Expense__c" />
注意:用戶至少對該對象具有讀取許可權,否則組件不會載入。
- 集合類型
下面為支援的集合類型:
類型 | 示例 | 描述 |
type[](Array) | <aura:attribute name=”colorPalette” type=”String[]” default=”[‘red’, ‘green’, ‘blue’]” /> | 自定義數組 |
List | <aura:attribute name=”colorPalette” type=”List” default=”[‘red’, ‘green’, ‘blue’]” /> | 有序的列表 |
Map | <aura:attribute name=”sectionLabels” type=”Map” default=”{ a: ‘label1’, b: ‘label2’ }” /> |
key:value集合。key不可重複。 如果不設置默認值,則在Javascript中默認設為null。 如果想設置空值,可寫為:default=”{}” |
Set | <aura:attribute name=”collection” type=”Set” default=”[‘red’, ‘green’, ‘blue’]” /> | 集合,無序,不含重複元素。 |
示例:
<aura:component controller="TestAuraController" access="global"> <aura:attribute name="selectedDisplayMonth" type="String" default="6 Months,12 Months,18 Months,24 Months,36 Months" /> <aura:iteration items="{!v.displayMonths}" var="displayMonth"> {!displayMonth} </aura:iteration> </aura:component >
- Apex Class類型
該類型屬性對應一個Apex類。
示例:
存在某個自定義Apex類:TestAura、
<aura:attribute name="color" type="docSampleNamespace.TestAura" />
- 指定框架類型
下面為支援的指定框架類型:
類型 | 示例 | 描述 |
Aura:component | N/A |
一個單獨的組件。 相比較而言,官方推薦使用Aura:component[]類型。 |
Aura:component[] |
<aura:component> <aura:attribute name="detail" type="Aura.Component[]"> <p>default paragraph1</p> </aura:attribute> Default value is: {!v.detail} </aura:component> |
利用該類型可以設置一個類型塊。 |
Aura.Action | <aura:attribute name =“ onclick” type =“ Aura.Action” /> | 使用此類型,可以將action傳遞給組件。 |
4.3 表達式
在3.4.2的組件屬性示例中,新建了一個屬性whom, 引用該屬性時使用了表達式:{!v.whom},負責該屬性的動態輸出。
語法:{!expression}
上述示例中,我們的屬性名稱定義為whom,v表示視圖(View)。當組件使用時,表達式的值將被評估並且動態替換。
注意:表達式區分大小寫。空格忽略。如果自定義欄位為myNamespace__Amount__c,要獲取該屬性值,必須寫為:{!v.myObject.myNamespace__Amount__c}
1) 表達式動態輸出
利用表達式是最簡單的值動態輸出方式。
表達式的值可以來自:component屬性,具體的數字,布爾值等。
示例:
component屬性:{!v.whom} ==> 輸出屬性名為whom的值 文字值:{!123}, {!'abc'} ==> 輸出分別為:123, abc 布爾值:{!true}, {!false} ==> 輸出分別為:true,false
注意:文字值中,“!”後面可以直接跟數字值,如果是字元則需要用單引號‘ ‘包起來,不包含則組件不會載入,用雙引號會報錯。
2) 條件表達式
- 三元表達式
與所有語言一樣,這裡也支援三元表達式,想必大家對三元表達式的概念都很清楚,這裡就不再解釋了。
示例:
{!v.displayMonth == '' ? 'No value' : 'Has value'}
displayMonth屬性值不為空字元,列印:Has value;
displayMonth屬性值為空字元,列印:No value
- <aura:if>標記
類似與Java中if-else
示例:
<aura:component> <aura:attribute name="read" type="Boolean" default="false" /> <aura:if isTrue="{!v.read}"> you can read it. <aura:set attribute="else"> you cannot read it. </aura:set> </aura:if> </aura:component>
read屬性值為:true,列印:you can read it.
read屬性值為:false,列印:you cannot read it.
3) 不同組件間數據綁定
當我們在在一個View中添加另一個組件,可以在父組件中初始化子組件的屬性值。目前有兩種語法格式:
語法1: <c:childComponent childAttr=”{!v.parentAttr}” />
綁定語法,將父組件中的parentAttr屬性和子組件的childAttr屬性關聯,初始化時將parentAttr的值傳遞給childAttr。運行中修改任意一個屬性,都會導致另外一個屬性值的改變。
示例:
parentAura.cmp
<!--Parent component--> <aura:component access="global"> <aura:attribute name="parentAttr" type="String" default="Parent Attribute" /> <!--實例化childAura組件--> <c:childAura childAttr="{!v.parentAttr}" /> <br/> parentAttr in parent: {!v.parentAttr} <div style="background:white"> <lightning:button label="Apply" onclick="{!c.applyHandle}" disabled="false" /> </div> </aura:component>
parentAuraController.js
({ applyHandle: function (cmp, event, helper) { cmp.set('v.parentAttr', 'Parent update'); } })
childAura.cmp
<!--Child component--> <aura:component> <aura:attribute name="childAttr" type="String" default="Child Attribute"/> <div class="slds-p-top--large" tyle="background:white"> childAttr in child: {!v.childAttr} <lightning:button label="Apply" onclick="{!c.applyHandle}" disabled="false" /> </div> </aura:component>
childAuraController.js
({ applyHandle : function(component, event, helper) { component.set('v.childAttr', 'Child update'); } })
output:
childAttr in child: Parent Attribute parentAttr in parent: Parent Attribute
點擊childAura組件的apply按鈕
childAttr in child: Child update parentAttr in parent: Child update
點擊parentAura組件的apply按鈕
childAttr in child: Parent update parentAttr in parent: Parent update
語法2: <c:childComponent childAttr=”{#v.parentAttr}” />
非綁定語法,將父組件中的parentAttr屬性和子組件的childAttr屬性關聯,初始化時將parentAttr的值傳遞給childAttr。運行中修改任意一個屬性,只改變當前屬性值,不會修改另外一個屬性值。
示例:
parentAura.cmp
<!--Parent component--> <aura:component access="global"> <aura:attribute name="parentAttr" type="String" default="Parent Attribute" /> <!--實例化childAura組件--> <c:childAura childAttr="{#v.parentAttr}" /> <br/> parentAttr in parent: {!v.parentAttr} <div style="background:white"> <lightning:button label="Apply" onclick="{!c.applyHandle}" disabled="false" /> </div> </aura:component>
parentAuraController.js
({ applyHandle: function (cmp, event, helper) { cmp.set('v.parentAttr', 'Parent update'); } })
childAura.cmp
<!--Child component--> <aura:component> <aura:attribute name="childAttr" type="String" default="Child Attribute"/> <div class="slds-p-top--large" tyle="background:white"> childAttr in child: {!v.childAttr} <lightning:button label="Apply" onclick="{!c.applyHandle}" disabled="false" /> </div> </aura:component>
childAuraController.js
({ applyHandle : function(component, event, helper) { component.set('v.childAttr', 'Child update'); } })
output:
childAttr in child: Parent Attribute parentAttr in parent: Parent Attribute 點擊childAura組件的apply按鈕 childAttr in child: Child update parentAttr in parent: Parent Attribute 點擊parentAura組件的apply按鈕 childAttr in child: Child update parentAttr in parent: Parent update
4.4 訪問控制
Aura框架可以通過access屬性自由的控制應用,組件,屬性,介面,事件,方法的訪問許可權。access屬性指定資源是否可以被所在命名空間之外使用。
使用範圍
可在如下tag中使用access屬性:
- <aura:application>
- <aura:component>
- <aura:attribute>
- <aura:interface>
- <aura:event>
- <aura:method>
access的值
- private:
- 可在應用,組件,介面,事件或者方法中使用, 不能被外部資源使用(命名空間)。
- 該值可以在<aura:attribute>或<aura:method>中使用。
- 將屬性標記為private會使得將來重構變得更加簡單(畢竟作用域小,所引發的影響也更小)。
- 除了在聲明該屬性的組件,其他組件調用該屬性時會返回undefined錯誤,所以即使繼承自該組件的子組件也不可訪問。
- public:
- 在當前org中都可以訪問。access的默認值便是public。
- global:
- 在所有的org中都可以訪問。
應用訪問控制
access在aura:application標籤中控制app是否可被所在命名控制之外訪問。
修飾符 | 描述 |
public | 僅在當前org中可用。access的默認值。 |
global | 在所有的org中可用。 |
組件訪問控制
access在aura:component標籤中控制app是否可被所在命名控制之外訪問。
修飾符 | 描述 |
public | 僅在當前org中可用。access的默認值。 |
global | 在所有的org中可用。 |
屬性訪問控制
access在aura:attribute標籤中控制app是否可被所在命名控制之外訪問。
修飾符 | 描述 |
private | 可在應用,組件,介面,事件或者方法中使用, 不能被外部資源使用(命名空間) |
public | 僅在當前org中可用。access的默認值。 |
global | 在所有的org中可用。 |
介面訪問控制
access在aura:interface標籤中控制app是否可被所在命名控制之外訪問。
修飾符 | 描述 |
public | 僅在當前org中可用。access的默認值。 |
global | 在所有的org中可用。 |
事件訪問控制
access在aura:event標籤中控制app是否可被所在命名控制之外訪問。
修飾符 | 描述 |
public | 僅在當前org中可用。access的默認值。 |
global | 在所有的org中可用。 |
示例:
<aura:component access="global"> ... </aura:component>
4.5 組件標記
在捆綁包中,以.cmp為後綴的文件稱為標記(Markup,可以理解為視圖),是捆綁包中唯一的必要資源,所以最精簡的捆綁包只包含一個.cmp文件即可。
標記可以包含文本或其他組件的引用,當然也可以聲明當前組件的元數據。
Hello, World!示例:
<aura:component> Hello, world! </aura:component>
在<aura:component>標籤中包含“Hello, world!”文本,當引用該組件時,會列印出“Hello, world”
在markup中集成了絕大多數HTML的標籤,例如<div>, <span>以及<br>等等。(也支援HTML5標籤)
示例:
<aura:component> <div class="container"> <!--Other HTML tags or components here--> </div> </aura:component>
4.6 css樣式
組件的樣式,我們一般在.css後綴文件中定義。
組件中的所有頂級元素都添加了一個特殊的.THIS CSS類,將命名空間添加到CSS文件中,可以有效防止當前組件的CSS樣式被其他組件的CSS文件覆蓋。如果CSS文件不按照該格式編寫,框架會拋錯誤。
示例:
testAura.cmp
<aura:component> <!--使用CSS中.THIS .WHITE類--> <div class="white"> Hello, world! </div> <!--頂級元素使用.THIS類--> <h2>Check out the style in this list.</h2> <div> <!--使用.THIS .RED類--> <li class="red">I'm red.</li> <!--使用.THIS .BLUE類--> <li class="blue">I'm blue.</li> <!--使用.THIS .GREEN類--> <li class="green">I'm green.</li> <!--沒有指定,使用當前模組樣式--> <li>I'm default.</li> </div> </aura:component>
testAura.css
.THIS { background-color: grey; } .THIS.white { background-color: white; } .THIS .red { background-color: red; } .THIS .blue { background-color: blue; } .THIS .green { background-color: green; }
輸出:
分析:從產生的結果來看,<h2>是頂級元素,直接使用了.css文件中.THIS類得到灰色背景;“I’m default”沒有指定顏色,使用當前模組<div>的樣式,而<div>是頂級元素,所以使用.THIS類得到灰色背景;其他的指定CSS類,顯示對應樣式。
5. 實戰案例分析
5.1 Parent組件
parentAura.cmp
<!--Parent component--> <!--controller類名:ParentAuraController--> <!--force:appHostable: 該組件可作為Lightning Experience的導航元素--> <!--flexipage:availabeForAllPageTypes: 可在Lightning App Builder中使用,也做作為Page使用--> <!--access=global: 該組件在所有的Orgs中都可以被引用--> <aura:component controller="ParentAuraController" implements="force:appHostable,flexipage:availableForAllPageTypes" access="global"> <aura:attribute name="displayMonths" type="String[]" /> <aura:attribute name="selectedDisplayMonth" type="String" /> <aura:attribute name="displayMonth" type="String" default="Last 6 Months"/> <aura:attribute name="read" type="Boolean" default="false" /> <!--組件初始化操作--> <aura:handler name="init" value="{!this}" action="{!c.handleInit}" /> <div class="white"> <lightning:layout multipleRows="true"> <lightning:layoutItem size="4" padding="around-small"> <!--下拉框選擇組件,selectedDisplayMonth為下拉框選擇的值,displayMonths為下拉框值列表--> <!--onchange: selectedDisplayMonth值改變時,調用controller.js中changeDisplayMonth函數--> <lightning:select name="displayMonthId" label="Select display months" aura:id="displayMonthId" value="{!v.selectedDisplayMonth}" required="true" onchange="{!c.changeDisplayMonth}"> <aura:iteration items="{!v.displayMonths}" var="displayMonth"> <option text="{!displayMonth}"></option> </aura:iteration> </lightning:select> </lightning:layoutItem> <lightning:layoutItem size="6" padding="around-small"> <div class="slds-p-top--large"> <!--按鈕組件,label為介面顯示值;onclick: 點擊按鈕時觸發controller.js中applyHandle函數--> <!--display: true表示按鈕灰掉,無法操作;false表示正常工作--> <lightning:button label="parentApply" onclick="{!c.applyHandle}" disabled="false" /> </div> </lightning:layoutItem> </lightning:layout> <lightning:layout multipleRows="true"> <lightning:layoutItem size="12" padding="around-small"> <li> <!--三元表達式--> <aura:if isTrue="{!v.read}"> you can read it. <aura:set attribute="else"> you cannot read it. </aura:set> </aura:if> </li> <li>displayMonth in parent: {!v.displayMonth}</li> </lightning:layoutItem> </lightning:layout> <lightning:layout multipleRows="true"> <lightning:layoutItem size="12" padding="around-small"> <!--實例化childAura組件--> <c:childAura childDisplayMonth="{!v.displayMonth}" /> </lightning:layoutItem> </lightning:layout> </div> </aura:component>
parentAura.css
.THIS { background-color: grey; } .THIS.white { background-color: white; }
parentAuraController.js
({ handleInit: function (cmp, event, helper) { // 初始化組件時,調用Help.js中getDisplayMonths函數,獲取下拉框值列表 helper.getDisplayMonths(cmp); }, changeDisplayMonth: function (cmp, event, helper) { console.log("displayMonths: " + cmp.get('v.displayMonths')) console.log("selected displayMonth: " + cmp.get('v.selectedDisplayMonth')); }, applyHandle: function (cmp, event, helper) { // 點擊parentApply按鈕時,將下拉框選中的值賦值給屬性displayMonth cmp.set('v.displayMonth', cmp.get('v.selectedDisplayMonth')); // 點擊parentApply按鈕時,將true賦值給屬性read. cmp.set('v.read', "true"); console.log("after click apply, displayMonth: " + cmp.get('v.displayMonth')); } })
parentAuraHelper.js
({ getDisplayMonths : function(cmp) { // 獲取controll.cls類中getDisplayMonths函數 var action = cmp.get("c.getDisplayMonths"); // 為該函數設置回調函數 action.setCallback(this, function (response) { var status = response.getState(); console.log("get displayMonths: " + status); // 判斷調用controller.cls類getDisplayMonths函數的響應狀態碼 if (status == "SUCCESS") { // 解析controller.cls傳回的響應,並賦值給變數repsonseBody var responseBody = JSON.parse(response.getReturnValue()); // 將變數responseBody賦值給組件屬性displayMonths(下拉框值列表) cmp.set("v.displayMonths", responseBody); } }); // 執行獲取數據行動 $A.enqueueAction(action); } })
ParentAuraController.cls
public with sharing class ParentAuraController { @AuraEnabled public static String getDisplayMonths() { List<String> displayMonths = new List<String>(); displayMonths.add('Last 6 Months'); displayMonths.add('Last 12 Months'); displayMonths.add('Last 18 Months'); displayMonths.add('Last 36 Months'); // 將響應序列化為Json格式 return JSON.serialize(displayMonths); } }
5.2 Child組件
childAura.cmp
<!--Child component--> <aura:component> <aura:attribute name="childDisplayMonth" type="String" default="child"/> <div class="slds-p-top--large"> <lightning:layout multipleRows="false"> <lightning:layoutItem size="4" padding="around-small"> displayMonth in child: {!v.childDisplayMonth} </lightning:layoutItem> <lightning:layoutItem size="4" padding="around-small"> <lightning:button label="childApply" onclick="{!c.applyHandle}" disabled="false" /> </lightning:layoutItem> </lightning:layout> </div> </aura:component>
childAura.css
.THIS { background-color: LightSkyBlue; }
childController.js
({ applyHandle : function(component, event, helper) { component.set('v.childDisplayMonth', 'Last 36 Months'); } })
5.3 案例分析
載入後如下圖所示:
分析:
- 初始化parentAura組件時,從controller.cls中獲取displayMonths值列表[“Last 6 Months”, “Last 12 Months”, “Last 18 Months”, “Last 36 Months”],默認載入第一個值,所以下拉框中為Last 6 Months.
- read屬性的默認值設為false,所以三元表達式中選擇else項,列印:you cannot read it.
- displayMonth的默認值設置為Last 6 Months, 列印:displayMonth in parent: Last 6 Months.
- 在parentAura組件中初始化childAura組件時,傳遞childDisplayMonth值等於displayMonth,所以該屬性值為Last 6 Months,而不使用默認值child,列印displayMonth in child: Last 6 Months.
更換下拉框值,並點擊parentApply按鈕:
分析:
- 下拉框選擇Last 12 Months,點擊parentApply按鈕時,調用parentAuraController.js中applyHandle函數。該函數中,將selectedDisplayMonth賦值給displayMonth,列印:displayMonth in parent: Last 12 Months;將read屬性重新賦值為true,所以三元表達式中選擇if項,列印:you can read it.
- 在parentAura組件中實例化childAura組件時,賦值childDisplayMonth採用的是綁定的方式{!**},所以修改parentAura組件中displayMonth屬性值時,同步修改childAura組件中childDisplayMonth值。(自己可以嘗試非綁定方式,查看結果如何)
點擊childParent按鈕:
分析:
- 點擊childApply按鈕,觸發childAura組件childAuraController.js的applyHandle函數,該函數重新賦值屬性childDisplayMonth等於Last 36 Months,列印:displayMonth in child: Last Months
- 在parentAura組件中實例化childAura組件時,賦值childDisplayMonth採用的是綁定的方式{!**},所以修改childAura組件中childDisplayMonth屬性值時,同步修改parentAura組件中displayMonth值。(自己可以嘗試非綁定方式,查看結果如何)
作者:吳家二少
部落格地址:https://www.cnblogs.com/cloudman-open/
本文歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接