文章來源:引入計算屬性、action、動態內容css
在主頁中增長一個Bootstrap的jumbotron
,在這個jumbotron
組件中增長一個input
輸入框和一個button
按鈕。html
爲了界面的美化在HTML代碼中使用了不少Bootstrap的樣式,更多有關Bootstrap的使用請自行學習。git
<div class="jumbotron text-center"> <div class="form-horizontal form-group form-group-lg row"> <div class="col-xs-10 col-xs-offset-1 col-sm-6 col-sm-offset-1 col-md-5 col-md-offset-2"> <input type="email" class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"/> </div> <div class="col-xs-10 col-xs-offset-1 col-sm-offset-0 col-sm-4 col-md-3"> <button class="btn btn-primary btn-lg btn-block">Request invitation</button> </div> </div> </div>
等待項目重啓完成,能夠在首頁看到以下效果頁面:github
計算屬性簡單講它就是一個特殊點的JS函數。若是你看過Ember.js 入門指南之三計算屬性(compute properties)相信使用起來會比較簡單,再次不過多介紹。正則表達式
下面幾點需求能夠經過計算屬性去實現:ubuntu
既然介紹了計算屬性那麼應該拿來用了!咱們使用屬性isDisabled
控制按鈕「Request invitation」是否可用。在button
標籤上增長一個HTML屬性disabled
,這個HTML屬性決定了按鈕button
是否可用。當HTML屬性disabled=true
時按鈕不可用,當HTML屬性disabled=false
時按鈕可用,那麼如何控制這個值是true
仍是false
呢?別忘了在Handlebars模板中能夠直接使用{{}}
表達式獲取屬性的值,下面修改模板index.hbs
,在標籤button
中增長屬性disabled
的設置:vim
<button class="btn btn-primary btn-lg btn-block" disabled={{isDisabled}}>Request invitation</button>
那要在哪裏控制isDisabled
的值呢?目前有2種方式,第一是在路由route
中控制這個值,另一種是在控制器controller
中控制這個屬性的值。有關路由的信息在前一篇已經簡單介紹過,或者看Ember.js 入門指南之二十路由定義學習。與路由同理,每一個模板都對應有一個同名的控制器controller
,若是你學習過MVC模式那麼你應該很清楚什麼是控制器,Ember中的控制器做用於MVC模式中的控制器類似,不過須要注意的是從Ember 3.0
以後控制器將再也不支持,因此呢!會在後面用組件替代控制器,官方也是這麼推薦的!更多有關控制器的介紹請看Controller Introduction。
一樣的咱們仍然是使用Ember CLI建立控制器,命令以下:api
ember g controller index
建立好控制器以後,在控制器內添加設置屬性isDisabled
的代碼:瀏覽器
// app/controller/index.js import Ember from 'ember'; export default Ember.Controller.extend({ isDisabled: true });
等待項目重啓完畢,能夠看到按鈕是不可用,若是你把屬性isDisabled
設置爲false
那麼按鈕是可用的。app
計算屬性和觀察者是Ember很是重要的特性。更多有關它們的特性請看下面的文章:
在下面的代碼中有關計算屬性部分使用的2.0
以後的語法,在2.0
以前計算屬性的語法是不同的(舊語法)。
修改模板index.hbs
,把郵箱號碼輸入框改成Ember的{{input}}
助手。
<!-- <input type="email" class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"/> --> {{input type="email" value=emailAddress class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"}}
等待項目重啓以後能夠看到界面並無變化。{{input}}
起到與原來代碼一樣的做用。
值得注意的是value=emailAddress
,並非value="emailAddress"
。你能夠在控制器中經過名字emailAddress
獲取輸入框的值。若是是value="emailAddress"
這種方式,輸入框的值默認一直都是"emailAddress",而且在控制器中不能使用屬性emailAddress
獲取值。這一點與日常咱們獲取<input>
輸入框的值有差異,一般獲取<input>
輸入框的值是經過name
屬性獲取的。修改控制器代碼,在控制器中增長個計算屬性和一個觀察器,以及一個普通屬性emailAddress
。
// app/controller/index.js import Ember from 'ember'; export default Ember.Controller.extend({ isDisabled: true, //設置默認值爲true emailAddress: '', // 設置默認值爲空字符串 // 定義一個計算屬性,當屬性emailAddress發生變化時會被執行不是主動執行的,是要有人調用才執行, // 好比執行:this.get('actualEmailAddress')去調用這個屬性纔會執行 actualEmailAddress: Ember.computed('emailAddress', function() { console.log('actualEmailAddress function is called: ', this.get('emailAddress')); }), // 定義一個觀察器,當屬性emailAddress發生變化時會自動執行,也就是說觀察器會檢測屬性emailAddress值的變化 emailAddressChanged: Ember.observer('emailAddress', function() { console.log('observer is called: ', this.get('emailAddress')); }) });
下面咱們作一個很是有趣的小測試。
等待頁面刷新完畢,打開瀏覽器控制檯,選擇標籤Ember
,在選擇左側的/# Route
,找到Controller
中名爲index
的,點擊$E
(以下圖紅色框出位置),而後再回到Console
標籤下。
點擊$E
在Console
下能夠看到相似Ember Inspector ($E): Class {__ember1459491972481: "ember470", __ember_meta__: Meta}
的信息。而後在控制檯命令輸入行輸入$E.get('actualEmailAddress')
代碼的做用是獲取計算屬性的值。能夠看到觸發了計算屬性方法,打印了日誌,以下截圖所示:
而後再次執行$E.get('actualEmailAddress')
計算屬性方法不會被執行,由於計算屬性檢測的屬性emailAddress
值並無發生變化,沒有發生變化,計算屬性方法不會被執行,手動修改輸入框的值,結果能夠看到計算屬性方法再次執行了,以下圖所示:
而後在控制檯命令行在輸入$E.set('emailAddress', 'example@example.com')
這句代碼意思是修改輸入框的值。能夠看到觀察器方法執行了,由於觀察器檢測到被檢測的屬性emailAddress
發生了變化,只要被檢測的屬性發生了變化就會自動執行。能夠看到以下截圖的日誌信息:
而且能夠看到郵箱號碼輸入框的值被置爲example@example.com
。而後在控制檯命令行再次輸入$E.set('emailAddress', 'example@example.com')
觀察器方法並不會執行了,即便你輸入屢次也不會執行,由於你輸入的值example@example.com
始終沒有變化。若是你稍微修改輸入的值那麼能夠看到觀察器又執行了。好比輸入$E.set('emailAddress', 'test')
,能夠看到控制檯再次打印了日誌信息。
測試觀察器還有另一種簡單的方法,就是直接在郵件輸入框直接輸入某些內容。能夠看到控制檯會隨着這輸入的內容變化而變化,感受就像是在檢測鍵盤事件同樣。下圖是我輸入12@qq.com
控制檯打印的日誌信息:
到此,我想你對計算屬性和觀察者應該有了必定的認識了!!
明白了計算屬性以後,用計算屬性重寫isDisabled
。控制器index.js
代碼修改以下:
// app/controller/index.js import Ember from 'ember'; export default Ember.Controller.extend({ // isDisabled: true, //設置默認值爲true emailAddress: '', // 設置默認值爲空字符串 isDisabled: Ember.computed('emailAddress', function() { return '' === this.get('emailAddress'); //判斷輸入框內容是否爲空 }) // 定義一個計算屬性,當屬性emailAddress發生變化時會被執行不是主動執行的,是要有人調用才執行, // 好比執行:this.get('actualEmailAddress')去調用這個屬性纔會執行 // actualEmailAddress: Ember.computed('emailAddress', function() { // console.log('actualEmailAddress function is called: ', this.get('emailAddress')); // }), // 定義一個觀察器,當屬性emailAddress發生變化時會自動執行,也就是說觀察器會檢測屬性emailAddress值的變化 // emailAddressChanged: Ember.observer('emailAddress', function() { // console.log('observer is called: ', this.get('emailAddress')); // }) });
直接把簡單屬性isDisabled
定義爲計算屬性,而且這個計算屬性檢測emailAddress
值的變化,若是emailAddress
值爲空那麼計算屬性isDisabled
的值爲true
不然值爲false
。從而實現判斷按鈕「Request invitation」是否可用。Ember封裝了不少字符串判斷方法,直接調用Ember封裝好的現成的方法,代碼再修改以下:
// app/controller/index.js import Ember from 'ember'; export default Ember.Controller.extend({ // isDisabled: true, //設置默認值爲true emailAddress: '', // 設置默認值爲空字符串 // isDisabled: Ember.computed('emailAddress', function() { // return '' === this.get('emailAddress'); //判斷輸入框內容是否爲空 // }) isDisabled: Ember.computed.empty('emailAddress') });
更多有關計算屬性封裝好的方法請看EMBER.COMPUTED NAMESPACE。
記得前面「計算屬性使用」這個小結提出了使用計算屬性實現多個需求,其中有一個是實現判斷輸入的郵箱號碼是不是正確格式的郵箱。如今再增長一個計算屬性isValid
判斷輸入的郵箱號碼的格式是否正確。而後再把這個計算屬性綁定到原來的計算屬性isDisabled
上。
// app/controller/index.js import Ember from 'ember'; export default Ember.Controller.extend({ emailAddress: '', // 設置默認值爲空字符串 emailAddress: '', // 設置默認值爲空字符串 // 使用正則表達式判斷郵箱格式,若是正確則返回true反之返回false isValid: Ember.computed.match('emailAddress', /^.+@.+\..+$/), // 把計算屬性isValid綁定到isDisabled上 isDisabled: Ember.computed.not('isValid') //當`disabled=false`時按鈕可用,因此正好須要取反 });
到此校驗問題基本實現了,等待項目重啓完成,能夠看到默認狀態下按鈕不可用,而且當你輸入的內容不符合郵箱格式時按鈕也是不可用的,若是輸入的內容是一個正確的郵箱那麼此時按鈕自動變爲可用狀態。很差截圖,就不截圖了!請讀者本身試驗!!
目前爲止,輸入檢驗也完成了,但你輸入正確郵箱後添加按鈕並不會發生任何事實,輸入的內容也沒有保存。下面開始介紹如何處理界面輸入的內容。
首先修改模板index.hbs
,在模板中增長一個{{action}}
標籤,有關Action請看Actions。
<button class="btn btn-primary btn-lg btn-block" disabled={{isDisabled}} {{action 'saveInvitation'}}>Request invitation</button>
僅僅修改了模板中<button>
標籤,其餘不變,保存等待項目重啓,此時在界面輸入正確的郵箱而後點擊按鈕你在瀏覽器的控制檯看到以下錯誤信息:
能看到錯誤信息說明你的項目是正確的,由於咱們並無定義saveInvitation
,在控制器index
中增長這個Action的定義。
// app/controller/index.js import Ember from 'ember'; export default Ember.Controller.extend({ // isDisabled: true, //設置默認值爲true emailAddress: '', // 設置默認值爲空字符串 emailAddress: '', // 設置默認值爲空字符串 // 使用正則表達式判斷郵箱格式,若是正確則返回true反之返回false isValid: Ember.computed.match('emailAddress', /^.+@.+\..+$/), // 把計算屬性isValid綁定到isDisabled上 isDisabled: Ember.computed.not('isValid'), //當`disabled=false`時按鈕可用,因此正好須要取反 actions: { saveInvitation: function() { // 注意alert中字符串兩邊使用的是 ` 不是單引號或者雙引號 alert(`Saving of the following email address is in propgress: ${this.get('emailAddress')}`); // 模擬保存操做 this.set('responseMessage', `Thank you! We've just saved your email address: ${this.get('emailAddress')}`); // 狀況輸入框內容 this.set('emailAddress', ''); } } });
注意:代碼alert
方法中並無使用單引號或者是雙引號囊括字符串「Saving of the following email address is in propgress: ${this.get('emailAddress')}」而是使用鍵盤tab
鍵頂部的~
鍵,這二者確定是有區別的,前者直接把${this.get('emailAddress')}
當着字符串,後者會把${this.get('emailAddress')}
當着表達式,從運行結果就能夠看出來了。
輸入正確郵箱後點擊按鈕會獲得以下截圖結果:
直接彈出提示信息這種方式太暴力了,改一種提示方式,修改模板index.hbs
,而後在註釋掉控制器index.js
中的alert
語句。
{{! app/templates/index.hbs}} <div class="jumbotron text-center"> <div class="form-horizontal form-group form-group-lg row"> <div class="col-xs-10 col-xs-offset-1 col-sm-6 col-sm-offset-1 col-md-5 col-md-offset-2"> <!-- <input type="email" class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"/> --> {{input type="email" value=emailAddress class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"}} </div> <div class="col-xs-10 col-xs-offset-1 col-sm-offset-0 col-sm-4 col-md-3"> <button class="btn btn-primary btn-lg btn-block" disabled={{isDisabled}} {{action 'saveInvitation'}}>Request invitation</button> </div> </div> {{! 顯示提示信息}} {{#if responseMessage}} <div class="alert alert-success">{{responseMessage}}</div> {{/if}} </div>
上述代碼新引入了一個表達式{{if}}
,顧名思義,這個表達式就是用於判斷的。更多有關判斷表達式的介紹請看Ember.js 入門指南之九handlebars條件表達式
等待項目重啓完成,再次測試。輸入正確格式的郵箱,點擊按鈕提交能夠看到以下的結果:
主要看綠色提示信息,相對於前一種直接彈框提示方式友好多了!!!
好了,到此第二篇也完成了。內容比較多須要耐心才能看完,若是你能認真堅持看到這裏相信你必定收穫了不少!!
做業要求
{{input}}
,須要校驗不爲空、校驗郵箱格式{{textarea}}
,須要校驗不爲空、輸入信息長度很多於5用到的組件和方法
{{input type="email" value=emailAddress class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"}}
{{textarea class="form-control" placeholder="Your message. (At least 5 characters.)" rows="7" value=message}}
判斷長度不小於5用到的方法。
Ember.computed.gte('propertyName', number);
而且判斷。
Ember.computed.and('firstProperty', 'secondProperty');
獲取屬性值的長度。
message.length
獲取計算屬性值長度
Ember.computed('propertyName', function() { return this.get('propertyName').get('length'); });
爲了照顧懶人我把完整的代碼放在GitHub上,若有須要請參考參考。博文通過屢次修改,博文上的代碼與github代碼可能有出入,不過影響不大!若是你以爲博文對你有點用,請在github項目上給我點個star
吧。您的確定對我來講是最大的動力!!