色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>數(shù)值算法/人工智能>

YY游戲云平臺(tái)控制臺(tái)實(shí)踐詳解

大?。?/span>0.5 MB 人氣: 2017-10-11 需要積分:1
 導(dǎo)語(yǔ):云平臺(tái)控制臺(tái),是一個(gè)典型的管控CRUD系統(tǒng),用于管理各種IaaS資源。為了使前端能達(dá)到仿客戶端體驗(yàn),同時(shí)保障代碼架構(gòu)清晰規(guī)范,易維護(hù),最終多玩YY選擇了AngularJS(1.x)作為云控制臺(tái)的前端框架。本文主要圍繞AngularJS(1.x),介紹多玩YY在開(kāi)發(fā)控制臺(tái)過(guò)程中的點(diǎn)點(diǎn)滴滴。
  為什么選擇AngularJS
  輕松構(gòu)建單頁(yè)面應(yīng)用
  可以說(shuō),這是我們最終選擇AngularJS的重要原因,如果你希望構(gòu)建一個(gè)結(jié)構(gòu)清晰、可維護(hù)、開(kāi)發(fā)效率高、體驗(yàn)好的單頁(yè)應(yīng)用,AngularJS是相當(dāng)不錯(cuò)的框架。
  單頁(yè)面應(yīng)用的魅力
  什么是單頁(yè)面應(yīng)用?單頁(yè)應(yīng)用,指一種基于Web的應(yīng)用或者網(wǎng)站,頁(yè)面永遠(yuǎn)都是局部更新元素,而不是整頁(yè)刷新,給用戶的感覺(jué)就像整個(gè)網(wǎng)站都是一個(gè)頁(yè)面。當(dāng)用戶點(diǎn)擊某個(gè)菜單或者按鍵時(shí),不會(huì)跳轉(zhuǎn)到其他頁(yè)面,前端會(huì)從后端獲取對(duì)應(yīng)頁(yè)面的數(shù)據(jù)而不是HTML,之后在頁(yè)面中需要更新內(nèi)容的地方,局部動(dòng)態(tài)刷新,而如果是傳統(tǒng)的多頁(yè)網(wǎng)站,當(dāng)用戶訪問(wèn)不同的頁(yè)面時(shí),服務(wù)器會(huì)直接返回一個(gè)HTML,然后瀏覽器負(fù)責(zé)將這個(gè)HTML展現(xiàn)給用戶。目前,大部分云控制臺(tái),都是單頁(yè)應(yīng)用架構(gòu),單頁(yè)應(yīng)用能帶來(lái)一種更近似客戶端,而不是網(wǎng)頁(yè)的體驗(yàn)。單頁(yè)面應(yīng)用網(wǎng)站,在體驗(yàn)方面,具有如下優(yōu)點(diǎn):
  做“頁(yè)面跳轉(zhuǎn)”時(shí),永遠(yuǎn)都是局部動(dòng)態(tài)刷新,用戶不會(huì)感覺(jué)整個(gè)屏幕閃了一下,而僅僅是需要變化的區(qū)域做了局部刷新。例如兩個(gè)不同的頁(yè)面,假設(shè)頁(yè)面元素都是一樣的,只是元素中的文字不一樣(例如每個(gè)頁(yè)面都有一個(gè)面包屑,一排按鈕及一個(gè)表格,這幾個(gè)元素的布局也是一樣的),當(dāng)用戶跳轉(zhuǎn)到另外一個(gè)頁(yè)面時(shí),會(huì)看到整個(gè)頁(yè)面并沒(méi)有重新渲染,只是文字發(fā)生了變化。簡(jiǎn)單地說(shuō),這有點(diǎn)類似使用App,永遠(yuǎn)都是局部發(fā)生變化,你見(jiàn)過(guò)哪個(gè)App,當(dāng)點(diǎn)擊到不同的功能視圖時(shí),整個(gè)屏幕會(huì)白屏閃一下的么?
  URL可收藏,可回退。如果瀏覽器的URL一直不變,那還不能稱為真正的單頁(yè)應(yīng)用。不同的功能,不同的資源頁(yè)面,對(duì)應(yīng)的URL是不一樣的。當(dāng)用戶跳轉(zhuǎn)到另外的功能時(shí),會(huì)發(fā)現(xiàn)URL會(huì)變成對(duì)應(yīng)的值;通過(guò)回退鍵,也可以回到之前瀏覽的頁(yè)面。這個(gè)特性有什么用呢?如果URL不會(huì)隨著功能而變化,當(dāng)用戶刷新當(dāng)前頁(yè)面時(shí),就會(huì)回到之前的默認(rèn)頁(yè)面,而不是預(yù)期的當(dāng)前功能頁(yè)面,同樣的,URL也不具備可收藏性,因?yàn)辄c(diǎn)開(kāi)之前收藏的URL,永遠(yuǎn)都是網(wǎng)站的默認(rèn)頁(yè)面。這對(duì)一些強(qiáng)交互的管控系統(tǒng)來(lái)說(shuō),體驗(yàn)不好。
  功能切換時(shí)快速流暢??焖倭鲿持饕?yàn)閮蓚€(gè)原因:一是頁(yè)面都是局部刷新,從用戶感官來(lái)說(shuō)更快;二是和后臺(tái)通信的內(nèi)容,都是數(shù)據(jù),而不是頁(yè)面模板,請(qǐng)求量更少;而傳統(tǒng)網(wǎng)站,在訪問(wèn)不同頁(yè)面時(shí),服務(wù)端返回的是HTML,體積更大,而且還需要一直重復(fù)加載Java、CSS文件。
  因?yàn)榫W(wǎng)站的單頁(yè)化,可以更好地使用全局類的交互(做頁(yè)面切換時(shí),需要一直保持不變的交互)。例如,頁(yè)面上需要顯示某次耗時(shí)操作的進(jìn)度,例如上傳文件進(jìn)度,耗時(shí)操作的當(dāng)前狀態(tài)等,你可以在頁(yè)面最右側(cè)固定顯示進(jìn)度。當(dāng)用戶訪問(wèn)單頁(yè)應(yīng)用時(shí),他會(huì)明白,當(dāng)點(diǎn)擊其他模塊時(shí),這個(gè)右側(cè)的通知欄不會(huì)消失,會(huì)固定顯示。而如果是多頁(yè)網(wǎng)站,用戶則會(huì)困惑,擔(dān)心自己跳轉(zhuǎn)到其他頁(yè)面后,進(jìn)度通知就會(huì)消失。
  AngularJS是開(kāi)發(fā)單頁(yè)應(yīng)用的利器
  單頁(yè)面應(yīng)用對(duì)于代碼分層,結(jié)構(gòu)清晰有更高的要求,而AngularJS是一個(gè)MVVM框架,其自身的約定,減少了我們寫出“一鍋粥”代碼的可能性(在下面討論“編寫更易維護(hù)的代碼”時(shí)會(huì)詳述)。
  AngularJS的著名第三方組件UI-Router,是一個(gè)控制頁(yè)面路由的組件,它支持我們快速搭建單頁(yè)應(yīng)用(AngularJS本身的路由功能也可以,但功能會(huì)稍微弱一些)。
  AngularJS的檢查更新機(jī)制,使頁(yè)面刷新時(shí)更加快速自然。 當(dāng)數(shù)據(jù)“可能”發(fā)生變化時(shí),AngularJS會(huì)檢查出所有變化的元素,再“一次性”刷新所有變化的UI元素。
  編寫更易維護(hù)的代碼
  很多人經(jīng)常會(huì)抱怨,不同水平的人湊在一起寫Java,到最后項(xiàng)目經(jīng)常就是一鍋粥,同一個(gè)Java文件里面,各種各樣的邏輯都混在一起,要增刪功能,簡(jiǎn)直是惡夢(mèng)。無(wú)規(guī)矩不成方圓。作為框架,AngularJS無(wú)疑能大大改善這種狀況,使得項(xiàng)目整體的分層明了,職責(zé)清晰。在筆者看來(lái),AngularJS能夠幫助我們編寫更易維護(hù)的代碼,一是因?yàn)槠洹瓣P(guān)注點(diǎn)分離”的理念,二是因?yàn)槠鋸?qiáng)大的特性為項(xiàng)目節(jié)省了不少代碼量,從而降低程序員犯錯(cuò)的概率。
  關(guān)注點(diǎn)分離
  關(guān)注點(diǎn)分離是AngularJS的一大設(shè)計(jì)哲學(xué)。所謂關(guān)注點(diǎn)分離,指的是各個(gè)邏輯層職責(zé)清晰明確。例如,當(dāng)你需要修改甚至替換展現(xiàn)層時(shí),無(wú)需關(guān)注業(yè)務(wù)層是怎么實(shí)現(xiàn)的。在AngularJS中,服務(wù)層(Ajax請(qǐng)求)- 業(yè)務(wù)層(Controller)- 展現(xiàn)層(HTML 模板)- 交互層(animation)這些都有對(duì)應(yīng)的基礎(chǔ)組件。不同組件職責(zé)不同,也很難將本屬于B組件的職責(zé)放到A組件上去實(shí)現(xiàn)。舉幾個(gè)例子:
  HTML及Controller需要協(xié)同工作,但職責(zé)分明。視圖、交互層面的邏輯,例如展示隱藏某些元素,是HTML模板的職責(zé),Controller只能用于數(shù)據(jù)初始化。如果你反其道而行,想在Controller中做HTML模板做的事情,將會(huì)非常別扭。這一點(diǎn)非常重要,傳統(tǒng)的Java代碼,經(jīng)常會(huì)出現(xiàn)的情況,就是Java里面會(huì)有大量DOM操作的邏輯,同時(shí)還有大量數(shù)據(jù)操作相關(guān)的邏輯,這些邏輯耦合到一起,當(dāng)需要單獨(dú)重構(gòu)數(shù)據(jù)層或者視圖層時(shí)(例如項(xiàng)目UI改版),都會(huì)捉襟見(jiàn)肘,同時(shí),由于Java代碼量的迅速膨脹,維護(hù)起來(lái)也會(huì)很麻煩。
  你無(wú)法將后臺(tái)通信邏輯放到Controller中實(shí)現(xiàn),而要放到Factory中。后臺(tái)通信邏輯,一般要做成公用的。而由于Controller之間是不能相互調(diào)用的,所以你也不可能將后臺(tái)通信邏輯放到其中一個(gè)Controller,然后其他Controller來(lái)調(diào)用這個(gè)Controller暴露的接口。唯一的辦法,就是將后臺(tái)通信邏輯放到Factory或者Service中。
  Filter及Directive看似都可以用于數(shù)據(jù)轉(zhuǎn)換,但實(shí)則不同。由于Filter只能做數(shù)據(jù)格式化,不支持引入模板,所以公用的UI交互,涉及到DOM元素或者需要引入HTML模板時(shí)時(shí),也只能通過(guò)Directive來(lái)實(shí)現(xiàn)。
  綜上所述,AngularJS項(xiàng)目,其展現(xiàn)層、交互層的邏輯,都是在HTML或者指令中,服務(wù)層(后臺(tái)通信),只適合出現(xiàn)在Factory(或者Service)中,而業(yè)務(wù)層則由Controller來(lái)負(fù)責(zé)。這樣每層的邏輯都是輕薄的,而不是糾結(jié)在一起。 如果你只是要優(yōu)化展示邏輯,那改改HTML就可以了,不用去管Controller是怎么寫的。這一點(diǎn)我們有親身體會(huì)。項(xiàng)目開(kāi)發(fā)過(guò)程中,我們重構(gòu)了視覺(jué)效果,所有的HTML都要重寫。但在重構(gòu)時(shí),我們的Controller、后臺(tái)通信(Service)、Filter基本都不用改,只要改HTML就行了。而如果項(xiàng)目是用jQuery寫的,顯然不可能做到,你需要重新為新的HTML增加一些可供jQuery選擇器使用的class或id,然后需要在Java里面綁定事件,根據(jù)新的CSS樣式名來(lái)寫新的交互效果,而在AngularJS上,有些不用做了(例如為了jQuery選擇器,而為HTML元素增加新的class、id;在Java中綁定事件),有些(例如交互效果)則只要改HTML就行,而不是改Java。
  AngularJS為我們省去的代碼量
  對(duì)于任何項(xiàng)目來(lái)說(shuō),代碼臃腫、冗余是可維護(hù)性的天敵。因此,實(shí)現(xiàn)同樣的功能,代碼量越少,抽象度越高,冗余度越低,在某種程度上意味著項(xiàng)目更方便維護(hù)。而能減少代碼量,也是AngularJS被推崇的一大優(yōu)點(diǎn)。讓我們來(lái)看看,它是如何減少了代碼量的:
  首先,作為一個(gè)大而全的框架(雙刃劍,有利有弊),AngularJS提供的諸多特性,使我們可以更專注于業(yè)務(wù)代碼的編寫。
  其次,AngularJS雙向數(shù)據(jù)綁定的特性,將我們從大量的值綁定代碼中解放出來(lái)。和jQuery對(duì)比,AngularJS不用為了選擇某個(gè)元素,而刻意為HTML加上一些跟樣式無(wú)關(guān)的class、2-2-2. id;不用寫一堆從HTML元素中取值,設(shè)值的代碼;不用在Java代碼中綁定事件;不用在Java值發(fā)生變化時(shí)寫代碼去更新HTML對(duì)應(yīng)的值。雙向數(shù)據(jù)綁定,讓我們告別很多簡(jiǎn)單無(wú)趣的綁定事件、綁定值的代碼。
  Directive、Filter、Factory等,天然的就是一個(gè)個(gè)可以復(fù)用的組件,減少了冗余重復(fù)代碼。一些需要公用的邏輯,如果放在Controller中,都會(huì)相當(dāng)別扭,就這樣被AngularJS“逼著”,把公用邏輯都放到Directive、Filter、Factory中去。
  開(kāi)發(fā)心得總結(jié)
  我理解的AngularJS基礎(chǔ)組件
  化繁為簡(jiǎn),幾大基礎(chǔ)組件的使用場(chǎng)景
  首先我們需要理清AngularJS幾個(gè)組件的使用場(chǎng)景。AngularJS的一個(gè)毛病,就是新概念,新特性太多,新手一下子要了解這么多,學(xué)習(xí)曲線略陡。為了幫助大家理解,總結(jié)下我理解的幾大組件使用場(chǎng)景。
  請(qǐng)求資源與數(shù)據(jù)緩存的東西放進(jìn)Service。Factory、Service本質(zhì)上都是Provider的語(yǔ)法糖,兩者只是使用方式有所不同,建議大家直接都用Service,ES6 class更容易,之后想平滑遷移到Angular2也會(huì)更容易,同時(shí)也能避免團(tuán)隊(duì)成員在選擇Service還是Factory時(shí)產(chǎn)生困惑。
  數(shù)據(jù)需要格式化的東西用Filter處理。例如把status值轉(zhuǎn)化為中文值,把時(shí)間戳轉(zhuǎn)成時(shí)間字符串之類。
  需要公用的DOM操作,放在指令中去寫。另外,如果需要引入jQuery組件,也可以寫個(gè)指令把jQuery組件初始化代碼放進(jìn)去。
  Controller與視圖按照一對(duì)一的關(guān)系維護(hù),在Controller內(nèi)初始化Scope對(duì)象與在Scope上添加方法(行為),為ViewModel做賦值。其他所有過(guò)程都不應(yīng)該出現(xiàn)在Controller中。Controller中不應(yīng)該出現(xiàn)和頁(yè)面展示、交互相關(guān)的代碼。例如展示隱藏某些元素之類,這些應(yīng)該是HTML模板或者指令負(fù)責(zé)。代碼越薄越好。
  全局常量值放到Constant。
  指令(Directive)魔法
  指令這個(gè)特性,用“魔法”一詞來(lái)形容它,都不為過(guò)。
  解決的痛點(diǎn):一言以蔽之,指令提供了一套前端組件化的方法及約定,這使得編寫,使用UI組件更加方便了。相對(duì)于jQuery,它解決了以下痛點(diǎn):
  動(dòng)態(tài)生成了HTML元素后,不用再手動(dòng)去為其加上Java特性。舉個(gè)例子:HTML原生的checkbox框比較丑,在jQuery時(shí)代,可以將checkbox替換成自定義的效果,如果是頁(yè)面一開(kāi)始就有的checkbox,我們可以在document.ready的時(shí)候調(diào)用自定義checkbox的初始化方法。但是,如果這個(gè)checkbox是動(dòng)態(tài)生成的,在每個(gè)動(dòng)態(tài)生成checkbox的地方,我們都得去調(diào)用checkbox的初始化方法,相當(dāng)麻煩。但用了AngularJS的指令,就不會(huì)有這個(gè)問(wèn)題了,只要在模板的chceckbox中加上指令,不管這個(gè)模板是動(dòng)態(tài)變化的還是靜態(tài)的,無(wú)需通過(guò)業(yè)務(wù)代碼來(lái)逐個(gè)調(diào)用初始化方法,呈現(xiàn)給用戶的,就已經(jīng)是AngularJS替換后的checkbox效果。
  一個(gè)組件的HTML和Java,是一個(gè)整體,而不是割裂的(題外話,這一點(diǎn)React做得比Angular1.x還要好)?;趈Query的UI組件,其引入方法,經(jīng)常是這樣的,首先,要求你自己copy一段指定的HTML,然后再調(diào)用初始化方法。而指令則支持定義對(duì)應(yīng)的模板HTML,用戶在引入時(shí),可能只要寫一個(gè)指令標(biāo)簽,就會(huì)自動(dòng)生成N行的HTML及綁定對(duì)應(yīng)的Java效果。當(dāng)然,理論上jQuery也能做到這樣,但是會(huì)比Angular的實(shí)現(xiàn)麻煩許多。
  應(yīng)用、移除UI特性時(shí)方便直觀。假設(shè)有這么一個(gè)需求,給一個(gè)普通輸入框增加輸入限制,只能輸入特定字符(如字母數(shù)字),寫好對(duì)應(yīng)指令,只要給這個(gè)input輸入框加上這個(gè)指令標(biāo)簽,就能馬上應(yīng)用這個(gè)特性,之后要移除,只要把標(biāo)簽去掉就好。相比之下,jQuery就會(huì)麻煩多。jQuery下,一般是通過(guò)元素選擇器來(lái)綁定Java效果。因此,在添加該特性時(shí),你需要考慮給對(duì)應(yīng)的輸入框指定一個(gè)合適的元素選擇器。移除特性時(shí),你要考慮:有可能你在動(dòng)態(tài)生成輸入框的地方,都加了這些初始化代碼,這些Java都需要移除;如果元素選擇器用的是class,得考慮是不是其他輸入框也有這個(gè)class,如果是,那么移除代碼時(shí)也會(huì)影響到其他輸入框。
  技巧
  如果你迫不得已需要引入jQuery組件,你可以寫一個(gè)指令把它包裝起來(lái),在該指令中初始化組件。
  要注意require參數(shù)中的值是駝峰的,在HTML中就得轉(zhuǎn)成對(duì)應(yīng)的中劃線命名,例如有require參數(shù)phoneKey,那么HTML中應(yīng)為phone-key=”xxx”。雖然這個(gè)道理很淺顯,但經(jīng)常一不小心就會(huì)弄錯(cuò)了,然后發(fā)現(xiàn)在指令內(nèi)部怎么著都拿不到require參數(shù)。
  如果你在link中加了elm.bind(‘click’),當(dāng)click回調(diào)函數(shù)中,作用域的值發(fā)生變化,記得調(diào)用scope.$apply(),否則值變化不會(huì)生效。
  文件、目錄約定
  目錄結(jié)構(gòu)
  第三方庫(kù)、CSS、圖片放置到哪個(gè)目錄,不在本文討論范圍,這里略過(guò)。需要進(jìn)一步說(shuō)明的,是業(yè)務(wù)代碼目錄。
  
  我們將系統(tǒng)自身的Java、HTML模板都放在pages目錄,其中子目錄common放置公用的Java及模板;其他子目錄,以功能模塊名作為目錄名,然后將這個(gè)模塊相關(guān)的Java及模板放在其中。這樣開(kāi)發(fā)同個(gè)模塊功能時(shí),可以方便地在HTML及對(duì)應(yīng)Java之間切換。有些代碼規(guī)范可能還會(huì)建議在模塊這一級(jí)目錄下,再根據(jù)AngularJS的幾大組件Controller、Filter、Service等,創(chuàng)建不同的子目錄,例如模塊A/controller,模塊A/service之類,我們則將所有Java及HTML放在同一級(jí),這樣做主要有幾個(gè)原因:
  我們的項(xiàng)目,平均每個(gè)模塊只有十來(lái)個(gè)文件,特別是每個(gè)模塊一般只有一個(gè)Filter及Service,為了這一個(gè)文件創(chuàng)建一個(gè)目錄,顯得多此一舉。
  通過(guò)文件名,已經(jīng)可以很方便地區(qū)分不同的Java組件類型及HTML模板類型,同時(shí),由于IDE一般會(huì)按照文件名字母排序,所以相同功能的Java及HTML會(huì)挨在一起,查找對(duì)應(yīng)的模板或Java代碼會(huì)方便很多。
  文件名約定
  這個(gè)約定對(duì)于Angular來(lái)說(shuō),特別重要。具體的約定是:
  
  例如,為“防火墻”模塊開(kāi)發(fā)“創(chuàng)建防火墻”的功能,它的Controller,對(duì)應(yīng)的Java為:firewall.create.ctrl.js,對(duì)應(yīng)的HTML模板為:
  firewall.create.ctrl.HTML。為了文件名書寫的方便,定義了組件的簡(jiǎn)寫:controller -》 ctrl ;factory,service -》 svr ; filter-》 fil ; directive -》 dire。
  這樣約定有兩個(gè)顯而易見(jiàn)的優(yōu)點(diǎn):
  通過(guò)文件名,就能知道對(duì)應(yīng)模塊、AngularJS基本組件類型、是模板HTML還是Java 。
  相同功能的Java及HTML,會(huì)挨在一起(如果IDE是按照文件命名排序)。
  與后端服務(wù)器通信
  根據(jù)后臺(tái)接口規(guī)范,結(jié)合AngularJS自身能力,我們做了一些封裝,使接口請(qǐng)求邏輯變得非常簡(jiǎn)單。具體問(wèn)題具體分析,先看看我們的后臺(tái)接口的標(biāo)準(zhǔn)響應(yīng)格式是怎樣的,前端會(huì)按照這個(gè)接口返回格式做一些定制:
  { errno:0, errmsg:“”, data:[ { id:“test”, name:“test”} ] }
  我們項(xiàng)目服務(wù)端的標(biāo)準(zhǔn)響應(yīng)是一個(gè)json,通過(guò)errno描述此次請(qǐng)求的結(jié)果碼,通過(guò)errmsg描述出錯(cuò)的原因(假如請(qǐng)求出錯(cuò)的話),通過(guò)data返回正常數(shù)據(jù)。
  出錯(cuò)處理
  當(dāng)接口返回的errno!=0時(shí),說(shuō)明接口返回異常(系統(tǒng)異?;蛴脩糨斎脲e(cuò)誤),這時(shí)我們希望能彈框提示用戶“出錯(cuò)了”。顯然,如果在每個(gè)接口請(qǐng)求邏輯中,都去寫這個(gè)邏輯,會(huì)非常累贅,所幸AngularJS提供了攔截器的功能,我們只要寫一個(gè)攔截器,就可以對(duì)所有的異常返回做統(tǒng)一處理。 首先,我們需要顯式地拋出HTTP錯(cuò)誤。因?yàn)楫?dāng)后臺(tái)邏輯出錯(cuò)或者用戶輸入?yún)?shù)有誤時(shí),返回的HTTP狀態(tài)碼都是200(這只是我們項(xiàng)目的約定),AngularJS并不會(huì)認(rèn)為200是出錯(cuò)的情況,因此,我們需要做點(diǎn)小動(dòng)作。
  $httpProvider.defaults.transformResponse.push(function(responseData){if(responseData.errno != 0) { throwresponseData; } …… });
  AngularJS的$httpProvider.defaults.transformResponse.push(下面簡(jiǎn)稱transformResponse)函數(shù),可以統(tǒng)一處理所有的HTTP響應(yīng)。在這里,我們就通過(guò)它捕獲了所有errno!=0的請(qǐng)求,并往外拋一個(gè)exception。接著,我們需要在$httpProvider.interceptors捕獲這個(gè)異常并彈框,代碼如下:
  $httpProvider.interceptors.push(function(){return{ responseError: function(response){if(response) { if(response.hasOwnProperty(“errmsg”)) { if(response.errno 》 0) { alert(response.errmsg); } else{ alert(“系統(tǒng)維護(hù)中,請(qǐng)稍候重試”); } } else{ if(response.status == 404) { alert(“抱歉,后臺(tái)服務(wù)出錯(cuò),找不到對(duì)應(yīng)的接口”); } else{ alert(“抱歉,后臺(tái)服務(wù)出錯(cuò)”); } } } } } });
  有些人可能會(huì)問(wèn),為啥不直接在一開(kāi)始的transformResponse函數(shù)中寫錯(cuò)誤處理邏輯呢?這是因?yàn)?,接口正常時(shí),AngularJS會(huì)依次調(diào)用transformResponse函數(shù),再調(diào)用interceptors的responseError。但是,某些異常情況,并不會(huì)調(diào)用transformResponse邏輯,例如,當(dāng)URL不存在時(shí),Web容器默認(rèn)返回的404頁(yè)面,或者當(dāng)程序出錯(cuò)時(shí),系統(tǒng)代碼未處理這個(gè)錯(cuò)誤,Web容器會(huì)返回默認(rèn)的500頁(yè)面,這時(shí)均會(huì)直接進(jìn)入interceptors的responseError中。因此,為了覆蓋所有的異常情況,需要在transformResponse中拋出異常,然后由responseError統(tǒng)一處理。
  2 響應(yīng)內(nèi)容格式化
  由于前端關(guān)心的數(shù)據(jù),是放在響應(yīng)內(nèi)容的data屬性中。而另外兩個(gè)屬性errno、errmsg,當(dāng)返回正常數(shù)據(jù)時(shí),前端是不關(guān)心的,為了取數(shù)據(jù)時(shí)更加方便,可以進(jìn)一步優(yōu)化transformResponse中的處理。當(dāng)errno==0時(shí),都返回responseData.data,這樣,在業(yè)務(wù)邏輯里面,就可以直接使用data了,而不用取xxx.data。
  $httpProvider.defaults.transformResponse.push(function(responseData){if(responseData && responseData.hasOwnProperty(“errno”) && responseData.hasOwnProperty(“errmsg”) && responseData.hasOwnProperty(“data”)) { if(responseData.errno == 0) { if(Angular.isArray(responseData.data) || Angular.isObject(responseData.data)) { returnresponseData.data; } else{ returnresponseData } } else{ throwresponseData; } } else{ returnresponseData; } });
  3 對(duì)$resource做進(jìn)一步封裝
  項(xiàng)目中每個(gè)模塊,都創(chuàng)建了對(duì)應(yīng)的service文件,用于與后臺(tái)進(jìn)行通信。例如“硬盤”模塊,對(duì)應(yīng)DiskSvr,“防火墻“模塊,對(duì)應(yīng)FirewallSvr。這樣劃分后,前端所有的后臺(tái)請(qǐng)求邏輯,找起來(lái)會(huì)很方便。
  在封裝后臺(tái)通信邏輯時(shí),我們用到$resource,這是AngularJS自身的一個(gè)組件,當(dāng)你的后臺(tái)接口符合RESTFul規(guī)范時(shí),你可以很方便地使用resource和后臺(tái)進(jìn)行通信。而由于我們的后臺(tái)并不是完整的RESTFul實(shí)現(xiàn),我們需要做一些簡(jiǎn)單的封裝。示意代碼如下:
  app.factory(“DiskSvr”, function(){varurl = “schedule/disk”; varcustomAPI = { clone: { method: “post”} } returngetApi(url, customAPI); }); //公用的,每個(gè)Svr都可以用getApi = function(path, customAPI){Angular.forEach(customAPI, function(value, key){if(!value.url) { value.url = util.connectPath(path, key); } else{ value.url = util.connectPath(path, value.url); } }); //所有的vardefaultAPI = { detail: { url: baseUrl + “/get”}, delete: { url: baseUrl + “/delete”, method: “delete”}, create: { url: baseUrl + “/create”, method: “post”}, update: { url: baseUrl + “/update”, method: “put”} } return$resource(path, {}, Angular.extend(defaultAPI, customAPI)); }
  上面的代碼,主要做了這些事情:
  為所有的svr注入了每個(gè)模塊接口都必備的,最基礎(chǔ)的增刪改查四個(gè)接口。這樣就無(wú)需在每個(gè)svr中加入這些接口。例如,在業(yè)務(wù)邏輯中調(diào)用DiskSvr.create(),就會(huì)用post請(qǐng)求調(diào)用schedule/disk/create接口。
  簡(jiǎn)化了新增接口的配置。新增一個(gè)接口,只要配置對(duì)應(yīng)的HTTP方法及名字即可。
  通過(guò)引用$resource組件、進(jìn)一步封裝及svr文件,在業(yè)務(wù)Controller中,不會(huì)看到任何的和后臺(tái)通信的基礎(chǔ)代碼,如果在這個(gè)Controller中你需要和后臺(tái)通信,你只需注入響應(yīng)的svr,然后調(diào)用對(duì)應(yīng)方法即可。
  4 注入請(qǐng)求header頭
  在我們的項(xiàng)目中,約定了所有的請(qǐng)求都要在header中帶上一些相同的信息,這對(duì)AngularJS來(lái)說(shuō),是非常簡(jiǎn)單的事情: 執(zhí)行以下代碼后,之后所有的HTTP請(qǐng)求都會(huì)帶上名為project的header信息:
  
  Controller間通信問(wèn)題
  Controller調(diào)用
  假設(shè)controllerA希望調(diào)用controllerB的某個(gè)函數(shù),告訴同伴Controller,我的某個(gè)你所關(guān)心的東西改變了,要怎么做呢?舉具體業(yè)務(wù)場(chǎng)景,有兩個(gè)Controller,一個(gè)是主頁(yè)Controller,另外主頁(yè)上有個(gè)彈框表單,這個(gè)彈框表單也有個(gè)Controller,用戶成功提交了這個(gè)表單后,彈框Controller需要告知主頁(yè)Controller,“哥們,請(qǐng)更新主頁(yè)上的某項(xiàng)數(shù)據(jù)”。建議的做法,是用AngularJS的消息機(jī)制。例如,上面的例子中,彈框Controller是主頁(yè)Controller的子Controller。那么彈框Controller可以往上冒泡傳遞消息:
  
  其父Controller去捕獲這個(gè)消息:
  
  這是一種很好的解耦辦法,假設(shè)這兩個(gè)Controller是由兩個(gè)開(kāi)發(fā)負(fù)責(zé)的,那么我開(kāi)發(fā)我的Controller,你開(kāi)發(fā)你的,我不用去關(guān)心你那邊的邏輯。
  2 數(shù)據(jù)共享
  多個(gè)Controller之間要共享數(shù)據(jù),要怎么做呢? 最簡(jiǎn)單但也不推薦的一個(gè)做法,就是把數(shù)據(jù)塞到rootscope中,但是,這就像Java的全局變量,野蠻不好控制。 這里推薦下我們的做法:寫一個(gè)專門用于存儲(chǔ)、設(shè)置共享數(shù)據(jù)的共享數(shù)據(jù)Facoty。在里面定義set方法,所有的共享變量,都需要經(jīng)過(guò)set方法來(lái)設(shè)置。然后取數(shù)據(jù)則通過(guò)DATA變量獲取。 偽代碼如下:
  app.factory(‘ShareSvr’, function(){varshareData = { peopleNum } return{ DATA:shareData, setPepleNum:function(num){shareData.peopleNum = num; } } }); app.controller(‘TestController’,function(ShareSvr){varself = this; this.DATA = ShareSvr.DATA; }
  這里并沒(méi)有要求DATA值只能通過(guò)galert(“Hello CSDN”);et方法獲取,是為了之后在Controller對(duì)應(yīng)的視圖HTML中取值方便些。
  第三方 庫(kù)/資源 推薦
  UI Router
  路由(route),幾乎所有的MVC框架都應(yīng)該具有的特性,它是前端構(gòu)建單頁(yè)面應(yīng)用(SPA)必不可少的組成部分。相比原生的ngRouter,UI Router功能更加強(qiáng)大,具備多視圖,嵌套路由等特性,可以解決路由大部分的應(yīng)用場(chǎng)景。
  ngDialog
  一個(gè)彈框控件,功能強(qiáng)大,我比較喜歡的地方,是它沒(méi)有寫死彈框的HTML、可以很方便地定義自己想要的彈框模板。例如,我們項(xiàng)目就通過(guò)它做了兩種彈框,一種是普通彈框,一種是側(cè)拉框(從屏幕右側(cè)滑出,占滿瀏覽器高度,寬度占滿一半屏幕(或者其他自定義寬度)。
  Angular-filter
  提供了很多實(shí)用的filter,string類、math類,集合類等。
  w5c-validator
  基于Angular.js原有的表單驗(yàn)證,統(tǒng)一驗(yàn)證規(guī)則和提示信息,在原有的基礎(chǔ)上擴(kuò)展了一些錯(cuò)誤提示的功能,讓大家不用在每個(gè)表單上寫一些提示信息的模板,專心的去實(shí)現(xiàn)業(yè)務(wù)邏輯,國(guó)人出品。
  ng-table
  輕量,功能強(qiáng)大的表格組件??梢院芊奖愕匦薷谋砀竦臉邮?、交互效果。
?

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

YY游戲云平臺(tái)控制臺(tái)實(shí)踐詳解下載

相關(guān)電子資料下載

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?
      主站蜘蛛池模板: 国产在线精品亚洲观看不卡欧美 | 久久99精品国产自在自线 | 国产99精品视频一区二区三区 | 老牛天天晚上夜噜噜噜 | 日韩做A爰片久久毛片A片毛茸茸 | 色内射无码AV | 久久精品亚洲视频 | 亚洲AV无码一区二区色情蜜芽 | 午夜婷婷精品午夜无码A片影院 | a色毛片免费视频 | 最新果冻传媒在线观看免费版 | 大桥未久电影在线观看 | 国内精品自线在拍2020不卡 | 丝袜美女被啪啪不带套漫画 | 陈红下面又紧又小好爽 | 韩国成人理伦片免费播放 | 麻豆国产96在线日韩麻豆 | 69ZXX少妇内射无码 | 久久综合色超碰人人 | 四虎精品久久 | 俺也去最新地址 | 久久成人a毛片免费观看网站 | 一个人在线观看视频免费 | 亚洲国语在线视频手机在线 | 欧美日韩无套内射另类 | 18日本人XXXXXX18 | 伸到同桌奶罩里捏她胸h | 新新电影理论中文字幕 | 18禁在线无遮挡羞羞漫画 | 女人的选择hd| 夜色88V精品国产亚洲AV | 九九久久国产精品免费热6 九九久久国产精品大片 | 欧美老妇与zozoz0交 | 日日碰狠狠添天天爽 | 超熟女专门志 | 久久热最新网站获取3 | 麻豆沈芯语| 一区三区三区不卡 | 日韩插啊免费视频在线观看 | 无限资源在线看影院免费观看 | 亚州免费一级毛片 |