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”>
<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/

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