1. 程式人生 > >Salesforce學習之路-developer篇(五)Aura元件原理及常用屬性

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">
<aura:component implements="c:myInterface">

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">
<aura:component implements="yournamespace:myInterface">

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/

本文歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線