Angular
創(chuàng)建模塊: var oneApp = angular.module("myApp",[ ] ) 第一個參數(shù)是模塊名茁瘦,第二個參數(shù)是填所依賴的模塊忧勿。返回模塊對象补胚。只傳一個參數(shù)是獲取蒂教。
-
給剛剛添加的oneApp模塊對象添加控制器肾扰,一定要在方法前注入要使用的$參數(shù):
oneApp.controller('oneController',[‘$scope’,’$http’,function($scope,$http)]
{ $scope.***=" "蛋逾; 賦值操作 //當(dāng)控制器執(zhí)行時自動運(yùn)行的函數(shù) }); 通過$scope與視圖關(guān)聯(lián)集晚。
```
由于壓縮代碼會改變參數(shù)名稱,注冊控制器的方法就通過第二個參數(shù)為數(shù)組的方式注入?yún)?shù)区匣,最后一個成員為原本的控制器函數(shù)偷拔,前面的成員都是需要注入的對象名稱。一個angular對象可以有多個controller
-
使用模塊時給要使用的區(qū)域
<div ng-app="myApp" ng-controller='oneController'> </div>
使用ng-app來聲明這里面包含的內(nèi)容要使用angular來管理沉颂。
可以給使用angular的標(biāo)簽里面添加ng-click="函數(shù)名( )",并在controller里用$scope.函數(shù)名=function( )來定義函數(shù)条摸,在click時調(diào)用悦污。
-
控制器的三種職責(zé):
- 為應(yīng)用中的模型設(shè)置初始狀態(tài)铸屉。
- 通過$scope對象把數(shù)據(jù)模型或函數(shù)對象傳遞給視圖。
- 利用$watch( )函數(shù)監(jiān)視模型的變化做出相應(yīng)的響應(yīng)切端。
$scope.$watch(“要監(jiān)視的變量名”彻坛,function(now,old){ //變量值改變時執(zhí)行})
為了防止Angular在未完全執(zhí)行完之前頁面顯示原本的HTML內(nèi)容踏枣,給最外層的div節(jié)點(diǎn)即添加了ng-app的節(jié)點(diǎn)添加ng-cloak屬性,并在css中設(shè)置[ng-cloak]{display:none},ng-cloak屬性在Angular加載完成后自動刪除昌屉。
ng-app 指令初始化一個 AngularJS 應(yīng)用程序。
ng-init 指令初始化應(yīng)用程序數(shù)據(jù)茵瀑。
ng-model 指令把元素值(比如輸入域的值)綁定到應(yīng)用程序间驮。AngularJS過濾器:可用于轉(zhuǎn)換數(shù)據(jù):
currency 格式化數(shù)字為貨幣格式。filter從數(shù)組項(xiàng)中選擇一個子集马昨。
lowercase格式化字符串為小寫竞帽。uppercase大寫。orderBy根據(jù)某個表達(dá)式排列數(shù)組鸿捧。-
$location服務(wù)屹篓,它可以返回當(dāng)前頁面的 URL 地址。$scope.myUrl = $location.absUrl();
$http 服務(wù)向服務(wù)器發(fā)送請求匙奴,應(yīng)用響應(yīng)服務(wù)器傳送過來的數(shù)據(jù)堆巧。 $http.get("welcome.htm").then(function (response) {$scope.my=response.data;}); $timeout 服務(wù)對應(yīng)了 JS window.setTimeout 函數(shù)。 $timeout(function(){$scope.myHeader = " ready?";}, 2000); $interval 服務(wù)對應(yīng)了 JS window.setInterval 函數(shù)泼菌。 $interval(function () {$scope.theTime=new Date().toLocaleTimeString();},1000);
- 所有的dom操作都應(yīng)該封裝到自定指令當(dāng)中谍肤!將復(fù)雜的HTML片段注入到頁面。
通過angular對象.directive(’指令名’,function(){所有的DOM操作都要在link函數(shù)里
return{ restrict: 'A', 表示能在屬性上使用哗伯,E表示只能當(dāng)表情使用荒揣,C表示只能當(dāng)類使用,M為在注釋里使用
link: function(scope, element, attr笋颤,controller) {參數(shù)代表使用這個指令的對象信息乳附,操作dom元素}}])
在link函數(shù)中可以給元素注冊事件利用element.on(‘事件名’内地,function(){});
使用時可以<指令名></指令名>來使用赋除。也可以當(dāng)做屬性放在標(biāo)簽中阱缓。還可以return一個templateUrl和replace參數(shù),templateUrl代表要添加的模板內(nèi)容举农,replace為true時清空之前標(biāo)簽內(nèi)的html替換為template荆针。
自定義指令時name采用駝峰命名法如tsHello使用時采用—的方式如te-hello。 - 想要按回車鍵時觸發(fā)事件給input加上form標(biāo)簽利用ng-submit=函數(shù)名來觸發(fā)颁糟。想要阻止表單的自動提交并刷新瀏覽器給form標(biāo)簽添加onsubmit=’return false’只有return false時候才能阻止自動提交航背。
- 使用angular時不要操作Dom元素,要想如何傳給控制臺參數(shù)并通過控制臺執(zhí)行相應(yīng)函數(shù)來改變視圖中的數(shù)據(jù)棱貌。
- 如果在控制器中調(diào)用js中的window時玖媚,需要通過依賴注入的$window對象,因?yàn)槊恳粋€控制器的代碼只是在它管轄的作用域中使用婚脱,通過這樣的寫法可以防止它與全局的window對象混淆今魔,出現(xiàn)各類詭異的異常!U厦场4砩!
- 給父子標(biāo)簽添加controller時子標(biāo)簽中的controller自動繼承父標(biāo)簽中controller中$scope的屬性和方法篮洁。
- 添加angular模板涩维。
- 首先構(gòu)建模板,創(chuàng)建type為‘text/ng-template’并含有id屬性的script標(biāo)簽袁波,標(biāo)簽內(nèi)寫入模板內(nèi)容瓦阐。<script type=‘text/ng-template’ id=‘模板名’>模板內(nèi)容</script>
- 然后在html中需要使用模板的地方加div,并設(shè)置ng-include锋叨、src=‘模板名’垄分、ng-controller。
- 之后再相應(yīng)的controller中設(shè)置模板所需要的值娃磺。
- angular中改變css樣式:
- 方法一:在標(biāo)簽中添加ng-class屬性并等于“{{$scope.樣式名}}”利用$scope.樣式名=…添加class薄湿。
- 方式二:可以一次添加多個標(biāo)簽,先設(shè)置值為布爾類型的$scope屬性偷卧,在標(biāo)簽中添加
ng-class=”{‘red’:$scope屬性,‘green’:$scope屬性}”當(dāng)對應(yīng)的屬性為true時添加該樣式名豺瘤。
- 自增長型id可能會因?yàn)榍懊娴脑乇粍h除后之后添加的id會與前一個id沖突,所以可以通過將id設(shè)置為random來保證id不會重復(fù)听诸。
- 不要在以數(shù)組長度為循環(huán)條件的情況下增加或刪除數(shù)組坐求,這樣會影響循環(huán)而且很傻。
- 改變url的哈希值利用$location.path(“a”)在地址后面添加# /a與路由一起實(shí)現(xiàn)頁面局部跳轉(zhuǎn)晌梨。
- 配置路由:當(dāng)請求來時用路由尋找到相應(yīng)的控制器
- 首先引入angular-route這個包桥嗤,在創(chuàng)建angular對象時第二個參數(shù)依賴?yán)锾钊搿痭gRoute’加引號P肫蕖!
```
之后用angular對象的config(‘$routeProvider’泛领,function($ routeProvider){
$routeProvider.when(‘/a’,{controller:對應(yīng)控制器名 荒吏,templateUrl:‘模板路徑’})
.when(‘/b’,{…} ) 利用when 來設(shè)置配置規(guī)則
.otherwise({redirect:’/a’})});
```
* 當(dāng)請求提交時路由模塊改變的是含ng-view屬性的標(biāo)簽渊鞋,將其中內(nèi)容替換成相應(yīng)的template绰更。
* 填入的模板路徑一定是相對于使用者的路徑而非controller的路徑。
* 填入哈希值時可以用’/student/:name?’冒號后面的被當(dāng)做占位符可以任意匹配加問號表示可以為空值锡宋。在controller里注入$ routerParmas.name可以得到name匹配到的值儡湾。
使用服務(wù)模塊,對于業(yè)務(wù)邏輯都應(yīng)該放入服務(wù)模塊中执俩,創(chuàng)建服務(wù)模塊:
angular對象.service(“mainService”徐钠,function(){ this.函數(shù)名=function(){}})添加業(yè)務(wù)邏輯。
使用時先將這個模塊注入到主要的angular對象奠滑,然后將service名mainService注入到controller中丹皱。過濾器:過濾器參數(shù)若是一個值則會在目標(biāo)對象的全部屬性中查找匹配妒穴。
若想執(zhí)行所查找的屬性則{{data|filter:{score:80}}}這樣過濾器只看對象中score屬性是否滿足條件宋税。
使用自定函數(shù)匹配{{data|filter:函數(shù)名}}添加函數(shù)$scope.函數(shù)名=function(e){}e為現(xiàn)過濾對象。返回true或false讼油。
23.在給圖片標(biāo)簽的src綁定地址時要用ng-src綁定杰赛,因?yàn)槿绻胹rc瀏覽器會在angular為啟動時請求圖片。-
用angular控制tab欄的樣式切換先使用ng-repeat來生成tab欄然后在點(diǎn)擊時觸發(fā)事件并根據(jù)id來改變對應(yīng)欄樣式矮台。
<li ng-repeat="list in li " ng-class='{"active":list.active}'
ng-click="activeChange(list.id)" >
```
使用ng-repeat時最好在后面加上track by id之類的唯一標(biāo)識屬性乏屯,在下次數(shù)據(jù)更新時頁面渲染速度回加快。
路由最好只定義一個when(“/:參數(shù)/:參數(shù)”…)通過修改參數(shù)$route.updataParams({參數(shù)名:參數(shù)值})來實(shí)現(xiàn)頁面的跳轉(zhuǎn)J莺铡3皆巍!用$scope.$on("$routeChangeSuccess", function () { })來監(jiān)聽地址欄的變化H肥:选!
還有一種可以選擇的跳轉(zhuǎn)方式就是用a標(biāo)簽的href屬性校辩,對應(yīng)不同情況來選擇跳轉(zhuǎn)方式窘问。想要在angular啟動時執(zhí)行某函數(shù)用$scope.init( )=function(){ }函數(shù)
路由的匹配也有順序,按when的照前后或者依賴注入的先后排序宜咒,先匹配上的先使用惠赫。沒有得到正確匹配一定要從路由的匹配順序上找問題!9屎凇儿咱!
-
angular中http的配置選項(xiàng):
- $http({可以配置內(nèi)容有method庭砍、url、data混埠、params逗威、transformRequest、transformResponse岔冀、cache凯旭、timeout})
- data屬性是一個對象,作為消息體的一部分發(fā)送給服務(wù)端
- params對應(yīng)一個字符串或?qū)ο笫固祝羰菍ο髣t自動按照json格式序列化并追加到url后面作為發(fā)送數(shù)據(jù)的一部分
- transformRequest用于請求體頭信息和請求體進(jìn)行序列化轉(zhuǎn)換罐呼,并生成一個數(shù)組發(fā)送給服務(wù)端,transformResponse則是解析服務(wù)端傳回的響應(yīng)體頭信息和響應(yīng)體信息侦高。
- $http服務(wù)是只能接受一個參數(shù)的函數(shù)嫉柴,這個參數(shù)是一個對象,包含了用來生成HTTP請求的配置內(nèi)容奉呛。這個函數(shù)返回一個promise對象咳胃,具有success和error兩個方法。success(function(data,status,config,headers){}袱箱。
CommonJS之Promises/A規(guī)范:通過規(guī)范API接口來簡化異步編程境析,使我們的異步邏輯代碼更易理解。
遵循Promises/A規(guī)范的實(shí)現(xiàn)我們稱之為Promise對象咆槽,Promise對象有且僅有三種狀態(tài):unfulfilled陈轿、fulfilled、failed秦忿;初始創(chuàng)建的時候是unfulfilled狀態(tài)麦射,狀態(tài)只可以從unfulfilled變成fulfilled,或者unfulfilled變成failed灯谣。狀態(tài)一旦變成fulfilled或者failed潜秋,狀態(tài)就不能再變了。
Promises/A規(guī)范提供了一個在程序中描述延時(或?qū)恚└拍畹慕鉀Q方案胎许,是一種處理異步編程的模式峻呛,可以有效解決回調(diào)的煩惱,并以一種同步的方式去處理業(yè)務(wù)流程呐萨。主要的思想不是執(zhí)行一個方法然后阻塞應(yīng)用程序等待結(jié)果返回后再回調(diào)其他方法杀饵,而是返回一個Promise對象來滿足未來監(jiān)聽。fulfilled狀態(tài)和failed狀態(tài)都可以被監(jiān)聽谬擦。Promise通過實(shí)現(xiàn)一個then接口來返回Promise對象來注冊回調(diào):
then(fulfilledHandler, errorHandler, progressHandler)切距;
then接口用于監(jiān)聽一個Promise的不同狀態(tài)。fulfilledHandler用于監(jiān)聽fulfilled狀態(tài)惨远,errorHandler用于監(jiān)聽failed狀態(tài)谜悟,progressHandler用于監(jiān)聽unfulfilled狀態(tài)话肖。Promise不強(qiáng)制實(shí)現(xiàn)unfulfilled(未完成)的事件監(jiān)聽。
在$htto請求中使用promise對象并不會帶來根本上的變化葡幸,但它會減少數(shù)據(jù)加載時的白框現(xiàn)象或者等待加載的時間最筒,在優(yōu)化用戶體驗(yàn)上將發(fā)揮明顯的作用。具體使用如下蔚叨。
```
angular.module('goodsList.serivice',[])
.factory('GoodsListFty',function($http,$q){
testPromise:function(){
//首先要定義一個延遲對象
var deferrd=$q.derfer();
//模擬異步請求訪問
serTimeout(function(){
deferrd.resolve("吃飯了")
}床蜘,5000);
//返回promise對象
return deferrd.promise;
}
})
```
在factory中創(chuàng)建蔑水,在controller中使用邢锯。Angular中需要配合$q一起使用。
Promise.then( )返回的對象給下一個.then( )使用鏈?zhǔn)骄幊痰姆绞较藢訉忧短椎穆闊┎蟊穑巩惒阶優(yōu)橥降で妗W詈髨?zhí)行finally內(nèi)的函數(shù)。then( )里面第一個匿名函數(shù)使成功時調(diào)用的方法歇父,第二個方法是失敗時調(diào)用蒂培。
```
console.log(1);
//通過方法獲取promise對象
var promise=GoodListFty.testPromise();
//通過then方法觸發(fā)狀態(tài)監(jiān)聽
promise.then(
function(data){
console.log(2);
return data;
},
function(reason){
}
).then(function(data){
console.log(7);
console.log(data);
}).finally(
function(){
console.log(3);
});
console.log(4);
```
在控制器中注入$rootScope對象使用時面對的是頁面中的各個控制器榜苫,通過$rootScope綁定的事件在各個控制器中都會觸發(fā)生效护戳,$scope只針對一個控制器。Angular中綁定事件調(diào)用obj.$on.(eventName,fn).
在angular中大部分操作之后的效果都是由$apply()方法自動在頁面中完成单刁,如果調(diào)用了非angular中的方法和函數(shù)如setTimeout方法后需要手動調(diào)用$apply方法來改變頁面中對應(yīng)的屬性值灸异。
在為標(biāo)簽綁定事件時可以傳入$event參數(shù),通過event常量返回當(dāng)前觸發(fā)事件的對象元素羔飞。
-
在使用插件ui-router時候可以使用angular的campoent寫法,一種較為簡便的angular寫法檐春。
angular.module('hellogalaxy').component('hello', {
template: '<h3>{{$ctrl.greeting}} Solar System!</h3>' +
'<button ng-click="$ctrl.toggleGreeting()">toggle greeting</button>',
controller: function() {
this.greeting = 'hello';
this.toggleGreeting = function() {
this.greeting = (this.greeting == 'hello') ? 'whats up' : 'hello'}}})
之后在$stateProvider中注冊state{name: 'hello',
url: '/hello',
component: 'hello'}
```
-
包含Service,factory,Provider三個子級概念逻淌,都是返回service(父級概念)對象
三種概念定義模塊的使用場景:- Factory:返回一個匿名對象,匿名對象中是方法的集合 return{各種方法}
- Service:在一個模塊中返回多個服務(wù)疟暖,適合用service創(chuàng)建模塊
- Provider:是service的底層實(shí)現(xiàn)卡儒,angular本身的東西,提供的服務(wù)
-
原聲JS中調(diào)用angular的$scope: 可以給$scope中添加原聲的JavaScript函數(shù)
var appElement= $('[ng-controller="myCtrl"]'); var $scope = angular.element(appElement).scope();
JSONP
由于默認(rèn)angular提供的異步請求對象不支持自定義回調(diào)函數(shù)名angular隨機(jī)分配的回調(diào)函數(shù)名稱不被豆瓣支持俐巴。
所以通過service自己寫方法來獲取豆瓣上的數(shù)據(jù)骨望。
使用時給controller注入'HttpService'通過HttpService.jsonp(url,data欣舵,callback)得到data數(shù)據(jù)擎鸠。
注意:在angular中如果通過自己寫的函數(shù)或第三方的庫來調(diào)用ajax請求必須要使用$apply(‘被改變的數(shù)據(jù)’)來通知angular$scope中的某個數(shù)據(jù)被改變,需要重新渲染缘圈。$scope.$apply()劣光;可以刷新所有的數(shù)據(jù)袜蚕。
(function(angular) {
// 由于默認(rèn)angular提供的異步請求對象不支持自定義回調(diào)函數(shù)名
// angular隨機(jī)分配的回調(diào)函數(shù)名稱不被豆瓣支持
var http = angular.module('moviecat.services.http', []);
http.service('HttpService', ['$window', '$document', function($window, $document) {
// url : http://api.douban.com/vsdfsdf -> <script> -> html就可自動執(zhí)行
this.jsonp = function(url, data, callback) {
// if (typeof data == 'function') {
// callback = data;
// }
var querystring = url.indexOf('?') == -1 ? '?' : '&';
for (var key in data) {
querystring += key + '=' + data[key] + '&';
}
var fnSuffix = Math.random().toString().replace('.', '');
var cbFuncName = 'my_json_cb_' + fnSuffix;
querystring += 'callback=' + cbFuncName;
var scriptElement = $document[0].createElement('script');
scriptElement.src = url + querystring;
// 不推薦
$window[cbFuncName] = function(data) {
callback(data);
$document[0].body.removeChild(scriptElement); //使用完后清除掉json文件
};
$document[0].body.appendChild(scriptElement);
};
}]);
})(angular);
利用scriptjs來實(shí)現(xiàn)異步加載庫,先引入angular-loader绢涡,因?yàn)閟criptjs異步加載可能會因?yàn)橛行┪募《崆凹虞d完成牲剃,在未加載完他的依賴庫就執(zhí)行導(dǎo)致錯誤,angular-loader會根據(jù)文件的依賴順序進(jìn)行異步加載
$script([
'./bower_components/angular/angular.js',
'./bower_components/angular-route/angular-route.js',
'./app.js' // 由于這個包比較小雄可,下載完成過后就直接執(zhí)行凿傅,為保證執(zhí)行順序要先引用angular-load
], function() { //庫全部加載完后執(zhí)行這個回調(diào)函數(shù)
console.log(angular);
angular.bootstrap(document, ['moviecat']);
});