Salesforce學習之路-developer篇(五)Aura元件原理及常用屬性
很喜歡曾經看到的一句話:以輸出倒逼輸入。以輸出的形式強制自己學習,確實是高效的學習方式,真的很棒。以下僅為個人學習理解,如有錯誤,歡迎指出,共同學習。
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/
本文歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線