摘要:文章來(lái)源引入計(jì)算屬性動(dòng)態(tài)內(nèi)容美化主頁(yè),增加郵件輸入框在主頁(yè)中增加一個(gè)的,在這個(gè)組件中增加一個(gè)輸入框和一個(gè)按鈕。如果是這種方式,輸入框的值默認(rèn)一直都是,并且在控制器中不能使用屬性獲取值。
文章來(lái)源:引入計(jì)算屬性、action、動(dòng)態(tài)內(nèi)容
美化主頁(yè),增加郵件輸入框在主頁(yè)中增加一個(gè)Bootstrap的jumbotron,在這個(gè)jumbotron組件中增加一個(gè)input輸入框和一個(gè)button按鈕。
在首頁(yè)index.hbs中增加靜態(tài)HTML代碼為了界面的美化在HTML代碼中使用了很多Bootstrap的樣式,更多有關(guān)Bootstrap的使用請(qǐng)自行學(xué)習(xí)。
等待項(xiàng)目重啟完成,可以在首頁(yè)看到如下效果頁(yè)面:
計(jì)算屬性計(jì)算屬性簡(jiǎn)單講它就是一個(gè)特殊點(diǎn)的JS函數(shù)。如果你看過(guò)Ember.js 入門(mén)指南之三計(jì)算屬性(compute properties)相信使用起來(lái)會(huì)比較簡(jiǎn)單,再次不過(guò)多介紹。
計(jì)算屬性使用下面幾點(diǎn)需求可以通過(guò)計(jì)算屬性去實(shí)現(xiàn):
當(dāng)輸入框的為空時(shí)按鈕“Request invitation”不可用
當(dāng)輸入的郵箱號(hào)碼格式不正確時(shí)按鈕“Request invitation”不可用
點(diǎn)擊按鈕“Request invitation”之后顯示響應(yīng)信息
數(shù)據(jù)保存完成之后情況郵箱輸入框的內(nèi)容
isDisabled屬性既然介紹了計(jì)算屬性那么應(yīng)該拿來(lái)用了!我們使用屬性isDisabled控制按鈕“Request invitation”是否可用。在button標(biāo)簽上增加一個(gè)HTML屬性disabled,這個(gè)HTML屬性決定了按鈕button是否可用。當(dāng)HTML屬性disabled=true時(shí)按鈕不可用,當(dāng)HTML屬性disabled=false時(shí)按鈕可用,那么如何控制這個(gè)值是true還是false呢?別忘了在Handlebars模板中可以直接使用{{}}表達(dá)式獲取屬性的值,下面修改模板index.hbs,在標(biāo)簽button中增加屬性disabled的設(shè)置:
那要在哪里控制isDisabled的值呢?目前有2種方式,第一是在路由route中控制這個(gè)值,另外一種是在控制器controller中控制這個(gè)屬性的值。有關(guān)路由的信息在前一篇已經(jīng)簡(jiǎn)單介紹過(guò),或者看Ember.js 入門(mén)指南之二十路由定義學(xué)習(xí)。與路由同理,每個(gè)模板都對(duì)應(yīng)有一個(gè)同名的控制器controller,如果你學(xué)習(xí)過(guò)MVC模式那么你應(yīng)該很清楚什么是控制器,Ember中的控制器作用于MVC模式中的控制器相似,不過(guò)需要注意的是從Ember 3.0之后控制器將不再支持,所以呢!會(huì)在后面用組件替代控制器,官方也是這么推薦的!更多有關(guān)控制器的介紹請(qǐng)看Controller Introduction。
同樣的我們?nèi)匀皇鞘褂肊mber CLI創(chuàng)建控制器,命令如下:
ember g controller index
創(chuàng)建好控制器之后,在控制器內(nèi)添加設(shè)置屬性isDisabled的代碼:
// app/controller/index.js import Ember from "ember"; export default Ember.Controller.extend({ isDisabled: true });
等待項(xiàng)目重啟完畢,可以看到按鈕是不可用,如果你把屬性isDisabled設(shè)置為false那么按鈕是可用的。
計(jì)算屬性與觀(guān)察者計(jì)算屬性和觀(guān)察者是Ember非常重要的特性。更多有關(guān)它們的特性請(qǐng)看下面的文章:
Ember.js 入門(mén)指南之三計(jì)算屬性
計(jì)算屬性官方參考文檔
Ember.js 入門(mén)指南之四觀(guān)察者
觀(guān)察者官方參考文檔
在下面的代碼中有關(guān)計(jì)算屬性部分使用的2.0之后的語(yǔ)法,在2.0之前計(jì)算屬性的語(yǔ)法是不一樣的(舊語(yǔ)法)。
修改模板index.hbs,把郵箱號(hào)碼輸入框改為Ember的{{input}}助手。
{{input type="email" value=emailAddress class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"}}
等待項(xiàng)目重啟之后可以看到界面并沒(méi)有變化。{{input}}起到與原來(lái)代碼同樣的作用。
值得注意的是value=emailAddress,并不是value="emailAddress"。你可以在控制器中通過(guò)名字emailAddress獲取輸入框的值。如果是value="emailAddress"這種方式,輸入框的值默認(rèn)一直都是"emailAddress",并且在控制器中不能使用屬性emailAddress獲取值。這一點(diǎn)與平常我們獲取輸入框的值有差別,通常獲取輸入框的值是通過(guò)name屬性獲取的。修改控制器代碼,在控制器中增加個(gè)計(jì)算屬性和一個(gè)觀(guān)察器,以及一個(gè)普通屬性emailAddress。
// app/controller/index.js import Ember from "ember"; export default Ember.Controller.extend({ isDisabled: true, //設(shè)置默認(rèn)值為true emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 // 定義一個(gè)計(jì)算屬性,當(dāng)屬性emailAddress發(fā)生變化時(shí)會(huì)被執(zhí)行不是主動(dòng)執(zhí)行的,是要有人調(diào)用才執(zhí)行, // 比如執(zhí)行:this.get("actualEmailAddress")去調(diào)用這個(gè)屬性才會(huì)執(zhí)行 actualEmailAddress: Ember.computed("emailAddress", function() { console.log("actualEmailAddress function is called: ", this.get("emailAddress")); }), // 定義一個(gè)觀(guān)察器,當(dāng)屬性emailAddress發(fā)生變化時(shí)會(huì)自動(dòng)執(zhí)行,也就是說(shuō)觀(guān)察器會(huì)檢測(cè)屬性emailAddress值的變化 emailAddressChanged: Ember.observer("emailAddress", function() { console.log("observer is called: ", this.get("emailAddress")); }) });
下面我們做一個(gè)非常有趣的小測(cè)試。
等待頁(yè)面刷新完畢,打開(kāi)瀏覽器控制臺(tái),選擇標(biāo)簽Ember,在選擇左側(cè)的/# Route,找到Controller中名為index的,點(diǎn)擊$E(如下圖紅色框出位置),然后再回到Console標(biāo)簽下。
點(diǎn)擊$E在Console下可以看到類(lèi)似Ember Inspector ($E): Class {__ember1459491972481: "ember470", __ember_meta__: Meta}的信息。然后在控制臺(tái)命令輸入行輸入$E.get("actualEmailAddress")代碼的作用是獲取計(jì)算屬性的值??梢钥吹接|發(fā)了計(jì)算屬性方法,打印了日志,如下截圖所示:
然后再次執(zhí)行$E.get("actualEmailAddress")計(jì)算屬性方法不會(huì)被執(zhí)行,因?yàn)橛?jì)算屬性檢測(cè)的屬性emailAddress值并沒(méi)有發(fā)生變化,沒(méi)有發(fā)生變化,計(jì)算屬性方法不會(huì)被執(zhí)行,手動(dòng)修改輸入框的值,結(jié)果可以看到計(jì)算屬性方法再次執(zhí)行了,如下圖所示:
然后在控制臺(tái)命令行在輸入$E.set("emailAddress", "[email protected]")這句代碼意思是修改輸入框的值??梢钥吹接^(guān)察器方法執(zhí)行了,因?yàn)橛^(guān)察器檢測(cè)到被檢測(cè)的屬性emailAddress發(fā)生了變化,只要被檢測(cè)的屬性發(fā)生了變化就會(huì)自動(dòng)執(zhí)行??梢钥吹饺缦陆貓D的日志信息:
并且可以看到郵箱號(hào)碼輸入框的值被置為[email protected]。然后在控制臺(tái)命令行再次輸入$E.set("emailAddress", "[email protected]")觀(guān)察器方法并不會(huì)執(zhí)行了,即使你輸入多次也不會(huì)執(zhí)行,因?yàn)槟爿斎氲闹?b>[email protected]始終沒(méi)有變化。如果你稍微修改輸入的值那么可以看到觀(guān)察器又執(zhí)行了。比如輸入$E.set("emailAddress", "test"),可以看到控制臺(tái)再次打印了日志信息。
測(cè)試觀(guān)察器還有另外一種簡(jiǎn)單的方法,就是直接在郵件輸入框直接輸入某些內(nèi)容。可以看到控制臺(tái)會(huì)隨著這輸入的內(nèi)容變化而變化,感覺(jué)就像是在檢測(cè)鍵盤(pán)事件一樣。下圖是我輸入[email protected]控制臺(tái)打印的日志信息:
到此,我想你對(duì)計(jì)算屬性和觀(guān)察者應(yīng)該有了一定的認(rèn)識(shí)了??!
用計(jì)算屬性修改isDisabled明白了計(jì)算屬性之后,用計(jì)算屬性重寫(xiě)isDisabled。控制器index.js代碼修改如下:
// app/controller/index.js import Ember from "ember"; export default Ember.Controller.extend({ // isDisabled: true, //設(shè)置默認(rèn)值為true emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 isDisabled: Ember.computed("emailAddress", function() { return "" === this.get("emailAddress"); //判斷輸入框內(nèi)容是否為空 }) // 定義一個(gè)計(jì)算屬性,當(dāng)屬性emailAddress發(fā)生變化時(shí)會(huì)被執(zhí)行不是主動(dòng)執(zhí)行的,是要有人調(diào)用才執(zhí)行, // 比如執(zhí)行:this.get("actualEmailAddress")去調(diào)用這個(gè)屬性才會(huì)執(zhí)行 // actualEmailAddress: Ember.computed("emailAddress", function() { // console.log("actualEmailAddress function is called: ", this.get("emailAddress")); // }), // 定義一個(gè)觀(guān)察器,當(dāng)屬性emailAddress發(fā)生變化時(shí)會(huì)自動(dòng)執(zhí)行,也就是說(shuō)觀(guān)察器會(huì)檢測(cè)屬性emailAddress值的變化 // emailAddressChanged: Ember.observer("emailAddress", function() { // console.log("observer is called: ", this.get("emailAddress")); // }) });
直接把簡(jiǎn)單屬性isDisabled定義為計(jì)算屬性,并且這個(gè)計(jì)算屬性檢測(cè)emailAddress值的變化,如果emailAddress值為空那么計(jì)算屬性isDisabled的值為true否則值為false。從而實(shí)現(xiàn)判斷按鈕“Request invitation”是否可用。Ember封裝了很多字符串判斷方法,直接調(diào)用Ember封裝好的現(xiàn)成的方法,代碼再修改如下:
// app/controller/index.js import Ember from "ember"; export default Ember.Controller.extend({ // isDisabled: true, //設(shè)置默認(rèn)值為true emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 // isDisabled: Ember.computed("emailAddress", function() { // return "" === this.get("emailAddress"); //判斷輸入框內(nèi)容是否為空 // }) isDisabled: Ember.computed.empty("emailAddress") });
更多有關(guān)計(jì)算屬性封裝好的方法請(qǐng)看EMBER.COMPUTED NAMESPACE。
isValid記得前面“計(jì)算屬性使用”這個(gè)小結(jié)提出了使用計(jì)算屬性實(shí)現(xiàn)多個(gè)需求,其中有一個(gè)是實(shí)現(xiàn)判斷輸入的郵箱號(hào)碼是否是正確格式的郵箱。現(xiàn)在再增加一個(gè)計(jì)算屬性isValid判斷輸入的郵箱號(hào)碼的格式是否正確。然后再把這個(gè)計(jì)算屬性綁定到原來(lái)的計(jì)算屬性isDisabled上。
// app/controller/index.js import Ember from "ember"; export default Ember.Controller.extend({ emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 // 使用正則表達(dá)式判斷郵箱格式,如果正確則返回true反之返回false isValid: Ember.computed.match("emailAddress", /^.+@.+..+$/), // 把計(jì)算屬性isValid綁定到isDisabled上 isDisabled: Ember.computed.not("isValid") //當(dāng)`disabled=false`時(shí)按鈕可用,所以正好需要取反 });
到此校驗(yàn)問(wèn)題基本實(shí)現(xiàn)了,等待項(xiàng)目重啟完成,可以看到默認(rèn)狀態(tài)下按鈕不可用,并且當(dāng)你輸入的內(nèi)容不符合郵箱格式時(shí)按鈕也是不可用的,如果輸入的內(nèi)容是一個(gè)正確的郵箱那么此時(shí)按鈕自動(dòng)變?yōu)榭捎脿顟B(tài)。不好截圖,就不截圖了!請(qǐng)讀者自己試驗(yàn)!!
添加Action到控制器目前為止,輸入檢驗(yàn)也完成了,但你輸入正確郵箱后添加按鈕并不會(huì)發(fā)生任何事實(shí),輸入的內(nèi)容也沒(méi)有保存。下面開(kāi)始介紹如何處理界面輸入的內(nèi)容。
首先修改模板index.hbs,在模板中增加一個(gè){{action}}標(biāo)簽,有關(guān)Action請(qǐng)看Actions。
僅僅修改了模板中標(biāo)簽,其他不變,保存等待項(xiàng)目重啟,此時(shí)在界面輸入正確的郵箱然后點(diǎn)擊按鈕你在瀏覽器的控制臺(tái)看到如下錯(cuò)誤信息:
能看到錯(cuò)誤信息說(shuō)明你的項(xiàng)目是正確的,因?yàn)槲覀儾](méi)有定義saveInvitation,在控制器index中增加這個(gè)Action的定義。
// app/controller/index.js import Ember from "ember"; export default Ember.Controller.extend({ // isDisabled: true, //設(shè)置默認(rèn)值為true emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 emailAddress: "", // 設(shè)置默認(rèn)值為空字符串 // 使用正則表達(dá)式判斷郵箱格式,如果正確則返回true反之返回false isValid: Ember.computed.match("emailAddress", /^.+@.+..+$/), // 把計(jì)算屬性isValid綁定到isDisabled上 isDisabled: Ember.computed.not("isValid"), //當(dāng)`disabled=false`時(shí)按鈕可用,所以正好需要取反 actions: { saveInvitation: function() { // 注意alert中字符串兩邊使用的是 ` 不是單引號(hào)或者雙引號(hào) 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")}`); // 情況輸入框內(nèi)容 this.set("emailAddress", ""); } } });
注意:代碼alert方法中并沒(méi)有使用單引號(hào)或者是雙引號(hào)囊括字符串“Saving of the following email address is in propgress: ${this.get("emailAddress")}”而是使用鍵盤(pán)tab鍵頂部的~鍵,這兩者肯定是有區(qū)別的,前者直接把${this.get("emailAddress")}當(dāng)著字符串,后者會(huì)把${this.get("emailAddress")}當(dāng)著表達(dá)式,從運(yùn)行結(jié)果就可以看出來(lái)了。
輸入正確郵箱后點(diǎn)擊按鈕會(huì)得到如下截圖結(jié)果:
直接彈出提示信息這種方式太暴力了,改一種提示方式,修改模板index.hbs,然后在注釋掉控制器index.js中的alert語(yǔ)句。
{{! app/templates/index.hbs}}{{! 顯示提示信息}} {{#if responseMessage}}{{input type="email" value=emailAddress class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"}}{{responseMessage}}{{/if}}
上述代碼新引入了一個(gè)表達(dá)式{{if}},顧名思義,這個(gè)表達(dá)式就是用于判斷的。更多有關(guān)判斷表達(dá)式的介紹請(qǐng)看Ember.js 入門(mén)指南之九handlebars條件表達(dá)式
等待項(xiàng)目重啟完成,再次測(cè)試。輸入正確格式的郵箱,點(diǎn)擊按鈕提交可以看到如下的結(jié)果:
主要看綠色提示信息,相對(duì)于前一種直接彈框提示方式友好多了!??!
好了,到此第二篇也完成了。內(nèi)容比較多需要耐心才能看完,如果你能認(rèn)真堅(jiān)持看到這里相信你一定收獲了很多!!
家庭作業(yè)作業(yè)要求
一個(gè)郵件輸入框{{input}},需要校驗(yàn)不為空、校驗(yàn)郵箱格式
一個(gè)消息輸入框{{textarea}},需要校驗(yàn)不為空、輸入信息長(zhǎng)度不少于5
上述兩個(gè)輸入框的校驗(yàn)都通過(guò)才允許提交
提交成功后在界面顯示提示信息
用到的組件和方法
{{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}}
判斷長(zhǎng)度不小于5用到的方法。
Ember.computed.gte("propertyName", number);
并且判斷。
Ember.computed.and("firstProperty", "secondProperty");
獲取屬性值的長(zhǎng)度。
message.length
獲取計(jì)算屬性值長(zhǎng)度
Ember.computed("propertyName", function() { return this.get("propertyName").get("length"); });
為了照顧懶人我把完整的代碼放在GitHub上,如有需要請(qǐng)參考參考。博文經(jīng)過(guò)多次修改,博文上的代碼與github代碼可能有出入,不過(guò)影響不大!如果你覺(jué)得博文對(duì)你有點(diǎn)用,請(qǐng)?jiān)趃ithub項(xiàng)目上給我點(diǎn)個(gè)star吧。您的肯定對(duì)我來(lái)說(shuō)是最大的動(dòng)力?。?/p>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79507.html
摘要:雖然計(jì)算屬性在大多數(shù)情況下更合適,但有時(shí)也需要一個(gè)自定義的偵聽(tīng)器,當(dāng)需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或開(kāi)銷(xiāo)較大的操作時(shí),通過(guò)偵聽(tīng)器最有用。路由的鉤子函數(shù)首頁(yè)可以控制導(dǎo)航跳轉(zhuǎn),,等,一般用于頁(yè)面的修改。 談?wù)勀銓?duì)MVVM開(kāi)發(fā)模式的理解 MVVM分為Model、View、ViewModel三者。Model 代表數(shù)據(jù)模型,數(shù)據(jù)和業(yè)務(wù)邏輯都在Model層中定義;View 代表UI視圖,負(fù)責(zé)數(shù)據(jù)的展示;...
摘要:只能是同步函數(shù),原因是無(wú)法捕捉異步函數(shù)的快照。除了這三個(gè)概念外,還有類(lèi)比計(jì)算屬性,用于從派生出一些值分割較大的狀態(tài)樹(shù),便于管理。處理表單可手動(dòng)監(jiān)聽(tīng)或是使用帶的雙向綁定計(jì)算屬性。 一、Vue組件的創(chuàng)建 一般語(yǔ)法: Vue.component(tagName, options) 務(wù)必在根組件實(shí)例化之前注冊(cè)組件 組件options說(shuō)明: data: 必須是一個(gè)函數(shù),目的在于返回獨(dú)立的對(duì)象...
摘要:載入前后在階段,實(shí)例的和都初始化了,但還是掛載之前為虛擬的節(jié)點(diǎn),還未替換。類(lèi)似于,不同在于提交的是,而不是直接變更狀態(tài)可以包含任意異步操作。 vue基礎(chǔ) 1、 router 路由與 a 標(biāo)簽的區(qū)別:https://www.jianshu.com/p/34b...2、 VUE雙向綁定的原理: 答:VUE實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理就是利用了 Object.defineProperty() 這個(gè)...
摘要:載入前后在階段,實(shí)例的和都初始化了,但還是掛載之前為虛擬的節(jié)點(diǎn),還未替換。類(lèi)似于,不同在于提交的是,而不是直接變更狀態(tài)可以包含任意異步操作。 vue基礎(chǔ) 1、 router 路由與 a 標(biāo)簽的區(qū)別:https://www.jianshu.com/p/34b...2、 VUE雙向綁定的原理: 答:VUE實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理就是利用了 Object.defineProperty() 這個(gè)...
摘要:接下來(lái),由簡(jiǎn)入繁依次實(shí)現(xiàn)提示組件的各個(gè)功能。那么第一個(gè)提示的定時(shí)器依然會(huì)錯(cuò)誤的關(guān)閉新提示。增強(qiáng)靈活性最后則是讓提示組件更靈活。 這次的教程里,我們要把組件化進(jìn)行到底!最近半年的幾個(gè)項(xiàng)目中,都遇到了需要使用Toast或者Notification組件的情況。在目前已有的一些基于Vue.js開(kāi)發(fā)的組件庫(kù),都沒(méi)有找到太合適的,所以自己重頭實(shí)現(xiàn)了一個(gè)。歷經(jīng)幾個(gè)項(xiàng)目的磨練,這個(gè)提示組件的功能已經(jīng)越...
閱讀 1590·2021-11-17 09:33
閱讀 1140·2021-11-12 10:36
閱讀 2445·2019-08-30 15:54
閱讀 2462·2019-08-30 13:14
閱讀 2949·2019-08-26 14:05
閱讀 3318·2019-08-26 11:32
閱讀 3033·2019-08-26 10:09
閱讀 3026·2019-08-26 10:09