溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

不可錯(cuò)過(guò)的Angular應(yīng)用技巧有哪些

發(fā)布時(shí)間:2021-11-17 14:05:25 來(lái)源:億速云 閱讀:89 作者:柒染 欄目:web開(kāi)發(fā)

本篇文章給大家分享的是有關(guān)不可錯(cuò)過(guò)的Angular應(yīng)用技巧有哪些,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

angular的核心思想是通過(guò)數(shù)據(jù)驅(qū)動(dòng)一切,其他東西都是數(shù)據(jù)的延伸。套用Javascript一切皆對(duì)象的思想,在angular中可以說(shuō)一切皆數(shù)據(jù)。 

(1) requirejs以及Yeoman關(guān)于項(xiàng)目構(gòu)建

在剛開(kāi)始接觸或者使用Angular的時(shí)候,總會(huì)疑惑與類似的問(wèn)題,我實(shí)踐的答案是不需要requirejs或者Yeoman.前者不使用,因?yàn)閍ngular本身有module的實(shí)現(xiàn).后者是因?yàn)锳ngular組織結(jié)構(gòu)以及項(xiàng)目構(gòu)建完全不必要弄得如此繁雜,手寫(xiě)或者在github上pull一個(gè)seed項(xiàng)目即可.

(2) 如何組織項(xiàng)目結(jié)構(gòu)

這個(gè)問(wèn)題有點(diǎn)廢材,因?yàn)橥耆蛉艘蝽?xiàng)目而異.個(gè)人推薦的是兩種組織結(jié)構(gòu),一種按照代碼功能,也就是controller都放在一個(gè)文件夾下,services都放在一個(gè)文件夾下.另一種則遵循所實(shí)現(xiàn)的功能,比如User就把對(duì)應(yīng)的template,services,controller都放在User文件夾下.

兩種都可以,從維護(hù)角度上看第二種會(huì)更好一些.

(3) controller以及service的劃分

這里controller通常就是一個(gè)頁(yè)面一個(gè)controller,假如一個(gè)頁(yè)面有公共的部分,公共部分永遠(yuǎn)使用一個(gè)controller.對(duì)于service要?jiǎng)澐殖蓛蓚€(gè)部分,一個(gè)是于服務(wù)器交互數(shù)據(jù)的service,另一個(gè)是一些功能性common的內(nèi)容,其中放置一些自己寫(xiě)的可復(fù)用的服務(wù),類似于notify等.

至于service要不要按照功能和模塊再進(jìn)一步劃分,這個(gè)就看項(xiàng)目來(lái)了.

(4) Angular插件以及庫(kù)的使用

對(duì)于一個(gè)項(xiàng)目所有的東西都去網(wǎng)上拿現(xiàn)成的肯定不現(xiàn)實(shí),但是所有的東西都自己寫(xiě)就更不實(shí)際了.Angular的很多插件是由Angular團(tuán)隊(duì)開(kāi)發(fā)出來(lái)或者一些人用jquery插件封裝的.我對(duì)于插件的觀點(diǎn)很簡(jiǎn)單,如果拿來(lái)用趕緊需求可以滿足就用,不能滿足就自己寫(xiě)或者在已有插件上改進(jìn).

對(duì)于如果你調(diào)試幾個(gè)小時(shí)還搞不定的插件,聽(tīng)我的勸,放棄它吧.大多數(shù)插件都是一些UI插件,大可不必追求繁雜,有時(shí)候簡(jiǎn)簡(jiǎn)單單的HTML控件也自有它簡(jiǎn)約的美.

如果你遇到Angular插件沖突,尤其是UI插件,大多數(shù)的情況下要放棄其中之一,比如angular-ui和angular-strap.

使用技巧

下面進(jìn)入正文,我會(huì)列舉出我在使用angular的過(guò)程中使用的一些技巧,會(huì)以場(chǎng)景的形式一一列舉.這里對(duì)于Angular的一些基礎(chǔ)概念我不會(huì)解釋,本文是一些技巧性的東西,不是基礎(chǔ)教程.

(1) angular中"{{}}"于Python的flask沖突

Python的flask使用的模板中,數(shù)據(jù)綁定也是通過(guò)兩個(gè)"{"大括號(hào),這就于angular的數(shù)據(jù)綁定有沖突.這個(gè)有兩種解決方法,一種是修改angular的綁定標(biāo)記,另一種就是修改flask的綁定標(biāo)記,這里兩種方案都給出.

修改angular:

$interpolateProvider.startSymbol('{[{').endSymbol('}]}');  // 將這句話加在config中即可,放在route的module中即可.這里將原來(lái)angular的{{ }}綁定,修改為通過(guò){[{ }]}綁定.

修改flask:

class CustomFlask(Flask):      jinja_options = Flask.jinja_options.copy()      jinja_options.update(dict(          block_start_string='{%',          block_end_string='%}',          variable_start_string='{#',          variable_end_string='#}',          comment_start_string='<#',          comment_end_string='#>',      ))         app = CustomFlask(__name__, instance_path='/web')

這里我推薦修改flask,因?yàn)橛昧薬ngular之后,前后端分離.flask的jinjia模板不再需要,同時(shí)如果你修改了Angular的綁定標(biāo)記,其他的控件和庫(kù)會(huì)有問(wèn)題的.

(2) 去除url中總是默認(rèn)帶有"#"

在設(shè)置route的時(shí)候,開(kāi)啟HTML5模式.

angular.module('router', ['ngRoute'])  .config(['$routeProvider', '$locationProvider',    function($routeProvider, $locationProvider) {      $locationProvider.html5Mode(true);   // 設(shè)置一下這句即可    }  ]);

3) ng-click="expression"以及類似的指令,如何在expression中書(shū)寫(xiě)多個(gè)表達(dá)式?

比如我在一個(gè)ng-click中想要給2個(gè)變量賦值,通過(guò)";"分號(hào)分割即可:

<a ng-click="obja=1;objb=2"></a>

(4) $watch沒(méi)有產(chǎn)生作用或者只生效一次

這種情況一般來(lái)說(shuō)是監(jiān)聽(tīng)一個(gè)字符串或者數(shù)字的時(shí)候會(huì)出現(xiàn),$scope.$watch("name",function(){}).沒(méi)有生效或者只生效一次,解決方法是$watch盡量監(jiān)聽(tīng)的是一個(gè)對(duì)象,將你要監(jiān)聽(tīng)的值附在一個(gè)Object下即可.

當(dāng)你使用angular-ui中的modal時(shí),這個(gè)比較明顯.

(5) 希望ng-view的內(nèi)容全頁(yè)面顯示

通常一個(gè)頁(yè)面可能會(huì)有固定的top-menu或者sidebar,這類固定不變的部分,然后每次route變化的都是ng-view的template,如果一個(gè)頁(yè)面希望整個(gè)頁(yè)面完全顯示它自己,不包括top-menu之類固定的部分.

這里通常是一個(gè)index.html和一個(gè)ng-view顯示的template.html,top-menu和sidebar位于index.html中,將它們的顯示隱藏通過(guò)ng-if綁定一個(gè)變量控制.

如果一個(gè)頁(yè)面需要自己完全顯示,不顯示sidebar等,則在其controller中通過(guò)$scope.$emit向上發(fā)送一個(gè)消息,然后index頁(yè)面的controller則通過(guò)$scope.$on監(jiān)聽(tīng)消息,一旦聽(tīng)到那個(gè)消息,則改變控制sidebar顯隱的變量.

也可以通過(guò)service做一個(gè)全局的變量控制,個(gè)人推薦還是通過(guò)消息廣播的方式.

(6) 切記用ng-if代替ng-show

這是angular的一個(gè)小坑,也可以說(shuō)是不大不小的一個(gè)坑.一些長(zhǎng)列表數(shù)據(jù),可能有一些東西是通過(guò)默認(rèn)隱藏,點(diǎn)擊顯示的形式展現(xiàn)的.而這部分可控制顯隱的內(nèi)容中也會(huì)伴隨很多數(shù)據(jù)綁定.這個(gè)在頁(yè)面渲染的時(shí)候非常影響性能.

舉一個(gè)列子,比如說(shuō)通常angular建議一個(gè)頁(yè)面的數(shù)據(jù)綁定不超過(guò)2000個(gè),假如現(xiàn)在有一個(gè)頁(yè)面直接綁定了2000個(gè)model,然后你加載,會(huì)發(fā)現(xiàn)非???如果你將每100的model設(shè)置為ng-show,默認(rèn)情況下不顯示,你會(huì)發(fā)現(xiàn)還是很卡.

然后你將所有的ng-show換成ng-if,你會(huì)發(fā)現(xiàn)性能瞬間快的像兩個(gè)應(yīng)用.原因在ng-show還是會(huì)執(zhí)行其中的所有綁定,ng-if則會(huì)在等于true,也就是顯示的時(shí)候再去執(zhí)行其中的綁定.這樣一來(lái)性能就有很大的提高,我之前通過(guò)這個(gè)簡(jiǎn)單的修改,頁(yè)面加載快了10倍左右.

所以在能使用ng-if的情況,用它代替所有的ng-show和ng-hide吧.

(7) 關(guān)于ng-bind-html

通常情況下為html元素綁定數(shù)據(jù),有ng-bind就夠了,但一些情境下需要綁定的不是一般的數(shù)據(jù),而是html.那么ng-bind就不夠用了,需要使用ng-bind-html,它會(huì)將內(nèi)容作為html格式輸出.比如想輸出帶有class的html,那么就使用ng-bind-html,而且還需要ngSanitize的配合,需要引入相應(yīng)的文件.

(8) 獲取ng-repeat數(shù)據(jù)filter后的結(jié)果

這個(gè)一般在搜索的時(shí)候需要用到,比如多重ng-repeat數(shù)據(jù)形成列表.然后filter一個(gè)字段,現(xiàn)在要得到filter之后的結(jié)果,有2中方式.

一種是在html的ng-repeat中類似這么寫(xiě):

ng-repeat="food in foodCategory._displayfoods = (foodCategory.foods | filter: { 'name': searchobj.foodfilter } | orderBy: food.sort_order)"

這樣_displayfoods就是filter后的最終顯示的結(jié)果.另一種方式是通過(guò)兩套數(shù)據(jù),一套寫(xiě)在controller中,然后filter以及orderBy都是在controller中操作,***操作的結(jié)果在用來(lái)ng-repeat.

***種方式比較方便,第二種方式更好,性能也好.

(9) ng-class以及ng-style通過(guò)判斷賦值

根據(jù)變量的值決定是否應(yīng)用某種class,以及不同的style樣式.

ng-class="{'state-error':!foodForm.foodstock.$valid}"  ng-style="{ color: i.color=='' || i.name=='活' ? 'default' : '#fff' }"

(10) form校驗(yàn)以input為例

angular的form可以通過(guò)input的HTML5屬性進(jìn)行校驗(yàn),這里主要通過(guò)form以及input的name屬性進(jìn)行鎖定,formname.inputname.$valid表示name為inputname的空間是否通過(guò)本身的屬性校驗(yàn).

(11) $resource和$http的$promise

$q.all([    resource.query().$promise,    resource2.query().$promise  ]).then(functon(success){    console.log(success);  },functon(error){    console.log(error);  });
foodFactory.food.save(f).$promise.then(function(result){    foodFactory.food.get({id:result.id}).$promise.then(function(data){    });  });

這個(gè)不解釋了,直接看就可以了,注意$http的promise需要手動(dòng)返回,所以一般情況下都通過(guò)$resource.

(12) 僅$watch監(jiān)聽(tīng)collection中的一個(gè)屬性

$watch的第三個(gè)參數(shù)設(shè)置為true,即可deep watch.不過(guò)有時(shí)候其實(shí)不想或者不需要監(jiān)聽(tīng)collection的全部屬性.只要監(jiān)視其中的一個(gè)或者幾個(gè),這時(shí)候通過(guò)for循環(huán)雖然可以循環(huán)$watch不過(guò)明顯太挫.

通過(guò)下面這種寫(xiě)法就可以監(jiān)控一個(gè)collection的單獨(dú)一個(gè)object屬性.

$scope.people = [      {          "groupname": "g1",           "persions": [              {                  "id": 1,                   "name": "bill"             },               {                  "id": 2,                   "name": "bill2"             }          ]      },       {          "groupname": "g2",           "persions": [              {                  "id": 3,                   "name": "bill3"             },               {                  "id": 4,                   "name": "bill4"             }          ]      }  ]     $scope.$watch(function($scope) {      return $scope.people.map(function(obj) {          return obj.persions.map(function(g){              return g.name          });      });  }, function (newVal) {      $scope.count++;      $scope.msg = 'person name was changed'+ $scope.count;  }, true);

(13) debounce防抖處理

這個(gè)對(duì)于頻繁出發(fā)的處理非常有用,適用于類似ng-change,$watch的一些場(chǎng)景.比如根絕關(guān)鍵字即時(shí)搜索的場(chǎng)合,將$debounce封裝為服務(wù),直接調(diào)用接口,代碼:http://jsfiddle.net/Warspawn/6K7Kd/

(14) 快速定位到某個(gè)位置

一般來(lái)講頁(yè)面內(nèi)通過(guò)<a id="bottom"></a>這樣的形式就可以結(jié)合js代碼,實(shí)現(xiàn)快速定位.在angular中也是通過(guò)類似的原理實(shí)現(xiàn),代碼如下:

var old = $location.hash();  $location.hash('batchmenu-bottom');  $anchorScroll();  $location.hash(old);

這樣寫(xiě)是因?yàn)橹苯觢ocation.hash會(huì)導(dǎo)致url變化,頁(yè)面跳轉(zhuǎn),所以加了防止跳轉(zhuǎn)的代碼.

以上就是不可錯(cuò)過(guò)的Angular應(yīng)用技巧有哪些,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI