看此篇博客前或者后,看一下trailhead可以加深印象以及理解的更好:https://trailhead.salesforce.com/modules/lex_dev_lc_basics
做過classic的朋友知道,前台和后台交互可以在頁面上使用多種方式,比如在VF page中apex:commandButton等標簽綁定action,使用actionFunction,使用ajax toolkit,使用VF Remoting或者使用action:support多種方式實現和后台的交互。如果你習慣性的使用了classic,那么你在lightning學習中可能有一點點的不適,最多的應該是沒法在lightning component中使用js了,因為lightning封裝了他的framework,這樣的好處為后期更容易維護,不必要因為維護別人的項目各種讀別人的rendered/reRender等惡心的事情,因為好多重新渲染元素的操作都在controller.js中處理了。當然,上面的都是泛泛而談,下面細節的說一下lightning的事件驅動模型。
一.Lightning模型介紹
Lightning事件驅動模型如下圖所示:
1.用戶在component標簽上點擊按鈕或者觸發某個自定義事件
2.javascript controller中的action獲取當前的事件源,處理業務邏輯,細節的對於后台的操作在helper中執行;
3.javascript helper中執行和server端的交互,調用后台apex controller,並在apex controller執行結束后調用回調函數去處理后期的業務邏輯以及更新UI等操作;
4.server-controller 使用apex代碼處理業務邏輯以及和數據庫的交互,寫法和VF Remoting的后台寫法類似,區別為需要在方法上添加標簽@AuraEnabled。

上一篇內容說過一個component bundle包含了很多內容,此篇通過上面的事件驅動模型主要說一下以下三個元素:Component(.cmp) / Controller js(.js) / Helper js(.js)
二. Component介紹
我們在Apex中經常使用Visualforce Component做一些公用組件,但是lightning中的component和剛才說的不是一個內容。一個component是一個包含了定義着的資源信息,標簽,也可以包含表達式或者是其他可選的資源,比如controller屬性信息,stylesheet等信息。lightning component中頭標簽為<aura:component>,所有的內容均需要在此內容中編寫。一個component中也可以嵌套其他的component,父子的component引用時,父的style sheet樣式會影響到子,使用時需要注意此點。針對Component更重要的是這個東西用在哪里,怎么用。
1.用在哪里:
Lightning Component可以用在很多的地方,如下圖所示。頭標簽的屬性實現不同的接口,則可以將此component用於不同地方。

- implements="force:appHostable" : 創建一個componet用於自定義的lightning tab;
- implements="flexipage:availableForAllPageTypes"and access="global" 創建一個component用於lightning page或者用於lightning app builder;
- implements="flexipage:availableForRecordHome,force:hasRecordId" and access="global" 創建一個component用於lightning的記錄home page,此種方式可以直接應用當前記錄的ID;
- implements="forceCommunity:availableForAllPageTypes" and access="global" 創建一個component用於Community Builder;
- implements="force:lightningQuickAction" 創建一個component用於quick action。
2.怎么用:
1) 創建Lightning Component
Lightning Component可以有多種創建的方式,使用sublime創建,使用develop console或者idea,本人常用sublime創建。在File->New->Lightning Component便可以新建一個lightning component。在新建的lightning component名稱處右鍵,便可以新建出來此lightning component bundle其他的組件,比如controller.js,helper.js等組件,如下圖所示。

2) Lightning Component 基礎知識
和classic 中的visualforce component很相像,一個lightning component可以嵌套另外一個lightning component,如果嵌套的component含有命名空間,則引入的方式為<yourNamespace:yourComponent/>如果沒有設置命名空間,則默認的命名空間為c,即<c:yourComponent/>
一個Lightning Component文件中可以引入多種元素,常用的元素如下:
- <aura:attribute>:此標簽用於聲明Component中需要引用的內容信息的變量。
- <aura:registerEvent>:此標簽用於引入自定義的注冊事件。
- <aura:handler>:此標簽用於處理自定義的注冊事件以及標准的事件,比如初始化(init)等handler。
- <ltng:require>: 此標簽用於引入靜態資源
- 元素標簽:lightning封裝了很多元素標簽,常用的可以歸納為容器(container)元素,按鈕(button)元素,導航(navigation)元素,可視化(Visual)元素,字段(Field)元素以及格式化(format)元素。
<aura:attribute>:做過classic的朋友都知道,一個頁面,后台使用成員變量,前台VF page可以用它來渲染元素。在lightning中,Component attribute很像apex中的成員變量,他們可以使用表達式語句應用在組件元素標簽中進行信息渲染。
attribute必須有兩個屬性:name以及type, aura:attribute寫法如下.
<aura:component> <aura:attribute name="testAttribute" type="string" default="test"/> test for {!v.testAttribute} </aura:component>
上面的demo聲明了一個類型為string的attribute,名稱為testAttribute。組件如果引用相關的屬性信息,引用方式為{!v. + attributeName}。lightning中,使用"v"去訪問attribute內容(v可以簡單的理解成view)。如果想要在后面設置attribute的值,也可以通過<aura:set attribute="anotherTestAttribute">來更改attribute值,aura:set通常可以和<aura:if>標簽一起使用,有興趣的可以自行查看。
attribute的type基本涵蓋了所有的類型,type取值如下:
基本類型:
- Boolean:定義一個布爾類型attribute。eg:<aura:attribute name="showDetail" type="Boolean" />
- Date:定義一個日期類型,不含Time,默認格式:YYYY-MM-dd。 eg: <aura:attribute name="startDate" type="Date" />
- Datetime:定義一個日期類型,含Time。eg:<aura:attribute name="lastModifiedDate" type="DateTime" />
- Decimal:定義一個浮點型小數,比Double類型更容易接收currency類型的數據。eg:<aura:attributename="totalPrice" type="Decimal" />
- Double: 定義一個double類型小數,通常可以被Decimal替代
- Integer:定義一個整數類型。eg:<aura:attribute name="numRecords" type="Integer" />
- Long:定義一個長整型類型,如果Integer盛裝不了,需要使用Long。eg:aura:attribute name="numRecords" type="Long" />
- String:定義一個字符串類型。eg:<aura:attribute name="message" type="String" />
(注:上述基本類型也可以使用數組類型,eg:<aura:attribute name="message" type="String[]" />)
函數類型:與javascript類型相一致的attribute 類型。
對象類型:定義一個自定義的object或者sObject類型。eg:<aura:attribute name="acc" type="Account" />
集合類型:
- type[](Array):聲明一個數組類型。eg:<aura:attribute name="colorPalette" type="String[]" default="['red','green', 'blue']" />
- List:聲明一個有序列表(和type[]相似,個人認為此處可以替代type[])。eg: <aura:attribute name="colorPalette" type="List" default="['red', 'green', 'blue']" />
- Map:聲明一個Map類型,包含鍵值對。eg:<aura:attribute name="testMap" type="Map" default="{a: 'label1', b:'label2' }" />
- Set:聲明一個無序列表。eg:<aura:attriute name="colorSet" type="Set" default="{'red','green','blue'}" />
自定義Java類型:如果創建Java類型,這個類必須要實現JsonSerializable接口。
特定的Frame-work類型(Framework-Specific):
- Aura.Action:傳遞一個action到lightning:component中。eg: <aura:attribute name="onclick" type="Aura.Action"/>
<aura:registerEvent>: 通常用於創建完自定義event后,將event注冊到component中,從而通過aura:handler將event進行裝載。event包含系統自帶的標准事件(init/change等)以及自定義事件,aura:registerEvent用於注冊自定義事件。
<aura:handler>: lightning中提供了一些標准和自定義事件,將事件裝載到lightning component中需要使用aura:handler。標准的事件舉例:init(lightning component初始化觸發,相當於VF page中的構造函數或者action聲明內容),change(某個aura:attribute改變自動觸發)。aura:handler寫法如下:
<aura:component> <aura:attribute name="childAttr" type="String" /> <aura:handler name="change" value="{!v.childAttr}" action="{!c.onChildAttrChange}"/> </aura:component>
上面的demo聲明了一個針對childAttr的change事件,當childAttr更改以后,便會執行controller.js的onChildAttrChange方法。
(點擊可查看event的Best Practice)
元素標簽:
aura framework提供了大量的可以直接使用的元素標簽用來開發,用戶也可以通過slds樣式更改成需要的樣式。官方提供了很多可以直接使用的標簽,以ui: / lightning: aura: 開頭。元素標簽的樣式使用slds進行渲染,如果想查看某個元素標簽樣式或者想要更改相關的樣式,可以先查看lightning design system中元素的渲染方式。元素標簽可以包含幾大類來匯總:
容器組件
lightning:accordion / lightning:accordionSection : 可折疊容器
lightning:card :卡牌裝容器,用於展示一組信息
lightning:layout/lightning:layoutItem : Grid容器
lightning:tab/lightning:tabset : Tab標簽
lightning:tile : 瓷磚模型,用於展示一條記錄的相關信息
按鈕組件
lightning:button: 普通按鈕
lightning:buttonIcon:只有一個html icon的按鈕
lightning:buttonMenu/lightning:menuItem: 一個drop-down 列表展示action
導航組件
lightning:breadcrumb/lightning:breadcrumbs: 展示當前操作記錄的層級導航
lightning:tree: 樹形結構
lightning:verticalNavigation: 垂直排列的鏈接列表
可視化組件
lightning:avatar: 對象的可視化表示 (一個圖像)
lightning:badge:包含少量信息的文本塊標簽
lightning:datatable: 顯示table布局
lightning:dynamicIcon: 動畫效果icon
lightning:helptext: hover后提示信息效果
lightning:icon: 顯示一個圖標
lightning:pill: 展示一個顯示X號的內容,可以顯示或者不顯示
lightning:progressBar: 展示一項操作的進程條
lightning:progressIndicator:進程指示器,顯示進程線
lightning:spinner: 顯示Loading圖形
字段組件
lightning:combobox :提供一個用戶輸入的並且可以autocomplete的控件
lightning:dualListbox : 兩個list間移動option。類似multi picklist效果
lightning:fileUpload : 提供上傳文件的框
lightning:fileCard : 展示一系列的上傳的文件
lightning:input : 默認展示輸入框,根據type不同展示不同效果。
lightning:radioGroup:展示一組單選按鈕
lightning:select:展示一個包含多個option的菜單
lightning:slider : 展示一個可以滑動效果指定范圍的輸入框
lightning:inputRichText: 富文本編輯器
lightning:textArea: textArea
格式化組件
以下標簽都是只讀的
lightning:formattedDateTime :格式化 data & time
lightning:formattedEmail :格式化 email
lightning:formattedLocation :使用經緯度格式化Location
lightning:formattedNumber :格式化數字
lightning:formattedPhone:格式化電話號碼
lightning:formattedRichText:格式化富文本區域
lightning:formattedText:格式化字符串
lightning:formattedUrl:格式化URL
一個元素標簽包含local ID,global ID。local id 作用域為當前的component,使用aura:id 屬性來創建一個local id。aura:id不支持表達式,只支持普通的字符串值作為local id.
local id 理論上是唯一的,但是不強制唯一,比如一組checkbox元素標簽,可以設置他們的local id是相同的。local id可以用於在javascript中通過local id獲取到元素本身或者元素列表。
eg:<lightning:input type="string" aura:id = "name" value="testValue" />
controller或者helper中可以通過cmp.find("name")即可獲取到 aura:id為name的元素(或者元素列表),如果不存在所要搜索的aura:id,則返回undefined.controller.js/helper.js中針對一個元素獲取它的local id,可以通過cmp.getLocalId()方法獲得。
Global id 很像classic中visualforce 元素組件中的id,運行時生成,並且是唯一的。
eg:<lightning:input type="string" id="name" value="testValue" />
global id可以用來區分不同元素的組件實例化或者用於debugging操作。針對一個組件元素獲取它的global id,可以通過cmp.getGlobalId()獲取。
三. Controller js介紹
因為component不允許寫任何的js,即使類似onclick="alert(xxx);"這種js也是被禁止的,所以controller js部分作用是至關重要的。他管理着Component中所有的事件驅動操作。
這里假設我們在'showMyInfo' componet中有一個按鈕名字是'Button1',綁定了一個'onclick'事件,onclick="{!c.handlerClick}".上面我們說過,針對元素組件引用attribute的值,使用v(v代表了view)。
當我們點擊按鈕或者觸發了注冊的事件后,會執行controller.js里面的方法,需要寫{!c.functionName},其中c可以理解為 client-side controller,functionName為在controller.js中聲明的方法名稱。
當我們為一個component bundle新建一個Controller js時,我們會發現,每個Controller方法里面默認都有3個參數:
- cmp : 代表當前操作的action所在的component,這里指的是showMyInfo
- event:代表當前action操作所觸發的事件,通過事件可以獲取到當前事件所對應的元素;
- helper:helper代表當前的componet對應的helper.js,當然這個參數不是必須的,helper文件可以寫js內容用來和后台server controller交互。當然,如果你想把和server controller交互的代碼寫在當前的controller js中,也是可以的。
cmp:我們通常用cmp可以獲取和設置attribute值,通過cmp.get('v.attributeName')即可獲取到lightning component中attribute名稱為attributeName的值。通過cmp.set('v.attributeName','testAttributeValue')即可設置lightning componet中名稱為attributeName的attribute的值為testAttributeValue.當然,cmp可不止獲取設置attribute值這么簡單,還可以通過cmp.getEvent('eventName')獲取注冊的事件等等。我們平時用的cmp比較多的功能就是這兩個了。
event:event代表當前操作的事件,比如當上面的用戶點擊了按鈕,可以通過event.getSource()獲取到事件源Button1以及獲取到事件源自身的屬性等信息;可以獲取到事件源的事件操作。
helper:helper代表了helper.js的實例化變量,你可以通過helper.helperMethod用來處理具體的邏輯,包括和后台交互;處理結果集;功能性的方法重用等等。因為有了helper,你的代碼有了更好的可讀性,可維護性以及可重用性。
下面通過幾行簡單的代碼來了解cmp以及event的用法。
- var btnClicked = event.getSource();此行代碼可以理解為獲取到點擊的button的dom element
- var btnMessage = btnClicked.get(''v.label"); 通過element的get方法可以獲取到這個元素上面的屬性值,獲取屬性值或者獲取其他的組件中的元素信息,需要使用'v.'來獲取;
- component.set("v.message", btnMessage); 更新component中名稱為message的attribute值。
- controller中有可能有多個方法,每個方法之間使用‘,’分隔;最后一個方法不能有‘,’。
({ handleClick: function(component, event, helper) { var btnClicked = event.getSource(); // the button var btnMessage = btnClicked.get("v.label"); // the button's label component.set("v.message", btnMessage); // update our message },
handleClick2: function(component,event,helper) {
}
})
四 Helper js 介紹
如果是controller.js負責了component中的所有業務邏輯,那么helper js就承包了所有的業務細節處理或者公用的方法(顯示隱藏loading等)。helper一般需要component這個參數,其他參數可以根據實際需要自動從controller.js獲取以及傳遞。這里舉例一個調用后台並對返回數據進行處理的例子。想要連接后台,需要准備以下的工作:
1.lightning component 的controller屬性設置此component后台引用的controller,用法和classic用法相同;
2.controller(后台)方法需要為靜態方法,並且需要添加@AuraEnabled注解。如果有classic經驗的可以想一下remote action的后台要求,把@RemoteAction改成@AuraEnabled就好。
createItem: function(component, camping) { var action = component.get("c.saveItem"); action.setParams({ "camping": camping }); action.setCallback(this, function(response){ var state = response.getState(); if (state === "SUCCESS") { var items = component.get("v.items"); items.push(response.getReturnValue()); component.set("v.items", items); } else if(status == "INCOMPLETE") {
console.log('execute');
} else if(status == "ERROR") {
console.log('error');
} }); $A.enqueueAction(action); }
上述例子功能為后台調用saveItem方法,camping作為參數傳遞到后台,然后異步調用。調用成功后將這個item寫入到前台的camping列表中。
其中有幾點需要注意:
1.我們通常使用component.get('v.something')來調用前台的一些屬性元素等,在這里使用component.get('c.backgroundMethod')可以調用到后台的方法;
2.通過setParam可以對方法設置參數,通過setCallBack可以對這個方法進行異步處理,我們通常會將這種調用后台的方法進行異步結果處理;
3.response的狀態主要有三種:SUCCESS/INCOMPLETE/ERROR。建議方法中將三種情況都進行處理,比如INCOMPLETE展示遮罩,ERROR/SUCCESS進行相應的業務處理以及解除遮罩等;
4.需要將action放在隊列里面,讓他排隊進行執行。$A為lightning中封裝的一個global變量,除了enqueueAction方法外還有很多常用的方法,后面會有涉及,有興趣的自行查看。
總結:此篇只是泛泛的對lightning componet常用的進行簡單的介紹,並沒有系統的介紹使用功能等,也沒有demo進行整體的連接。有興趣的可以自己查看文檔或者trailhead等學習資料,后期將會寫一些細節的使用。有錯誤的地方歡迎指出,有不懂的歡迎提問。
