Angular
1.創建模塊: var oneApp = angular.module("myApp",[ ] ) 第一個參數是模塊名,第二個參數是填所依賴的模塊。返回模塊對象。只傳一個參數是獲取。
2.給剛剛添加的oneApp模塊對象添加控制器,一定要在方法前注入要使用的$參數:
oneApp.controller('oneController',[‘$scope’,’$http’,function($scope,$http)]
{ $scope.***=" "; 賦值操作 //當控制器執行時自動運行的函數 }); 通過$scope與視圖關聯。
由于壓縮代碼會改變參數名稱,注冊控制器的方法就通過第二個參數為數組的方式注入參數,最后一個成員為原本的控制器函數,前面的成員都是需要注入的對象名稱。一個angular對象可以有多個controller
3.使用模塊時給要使用的區域
<div ng-app="myApp" ng-controller='oneController'> </div>
使用ng-app來聲明這里面包含的內容要使用angular來管理。
4.可以給使用angular的標簽里面添加ng-click="函數名( )",并在controller里用$scope.函數名=function( )來定義函數,在click時調用。
5.控制器的三種職責:
·為應用中的模型設置初始狀態。
·通過$scope對象把數據模型或函數對象傳遞給視圖。
·利用$watch( )函數監視模型的變化做出相應的響應。
$scope.$watch(“要監視的變量名”,function(now,old){ //變量值改變時執行})
6.為了防止Angular在未完全執行完之前頁面顯示原本的HTML內容,給最外層的div節點即添加了ng-app的節點添加ng-cloak屬性,并在css中設置[ng-cloak]{display:none},ng-cloak屬性在Angular加載完成后自動刪除。
7.ng-app 指令初始化一個 AngularJS 應用程序。
ng-init 指令初始化應用程序數據。
ng-model 指令把元素值(比如輸入域的值)綁定到應用程序。
8.AngularJS過濾器:可用于轉換數據:
currency 格式化數字為貨幣格式。filter從數組項中選擇一個子集。
lowercase格式化字符串為小寫。uppercase大寫。orderBy根據某個表達式排列數組。
9.$location服務,它可以返回當前頁面的 URL 地址。
$scope.myUrl = $location.absUrl();
$http 服務向服務器發送請求,應用響應服務器傳送過來的數據。
$http.get("welcome.htm").then(function (response) {$scope.my=response.data;});
$timeout 服務對應了 JS window.setTimeout 函數。
$timeout(function(){$scope.myHeader = " ready?";}, 2000);
$interval 服務對應了 JS window.setInterval 函數。
$interval(function () {$scope.theTime=new
Date().toLocaleTimeString();},1000);
10.所有的dom操作都應該封裝到自定指令當中!將復雜的HTML片段注入到頁面。
通過angular對象.directive(’指令名’,function(){所有的DOM操作都要在link函數里
return{ restrict: 'A', 表示能在屬性上使用,E表示只能當表情使用,C表示只能當類使用,M為在注釋里使用
link: function(scope, element, attr,controller) {參數代表使用這個指令的對象信息,操作dom元素}}])
在link函數中可以給元素注冊事件利用element.on(‘事件名’,function(){});
使用時可以<指令名></指令名>來使用。也可以當做屬性放在標簽中。還可以return一個templateUrl和replace參數,templateUrl代表要添加的模板內容,replace為true時清空之前標簽內的html替換為template。
自定義指令時name采用駝峰命名法如tsHello使用時采用—的方式如te-hello。
11.想要按回車鍵時觸發事件給input加上form標簽利用ng-submit=函數名來觸發。想要阻止表單的自動提交并刷新瀏覽器給form標簽添加onsubmit=’return false’只有return false時候才能阻止自動提交。
12.使用angular時不要操作Dom元素,要想如何傳給控制臺參數并通過控制臺執行相應函數來改變視圖中的數據。
13.如果在控制器中調用js中的window時,需要通過依賴注入的$window對象,因為每一個控制器的代碼只是在它管轄的作用域中使用,通過這樣的寫法可以防止它與全局的window對象混淆,出現各類詭異的異常?。。?!
14.給父子標簽添加controller時子標簽中的controller自動繼承父標簽中controller中$scope的屬性和方法。
15.添加angular模板。
·首先構建模板,創建type為‘text/ng-template’并含有id屬性的script標簽,標簽內寫入模板內容。<script type=‘text/ng-template’ id=‘模板名’>模板內容</script>
·然后在html中需要使用模板的地方加div,并設置ng-include、src=‘模板名’、ng-controller。
·之后再相應的controller中設置模板所需要的值。
16.angular中改變css樣式:
·方法一:在標簽中添加ng-class屬性并等于“{{$scope.樣式名}}”利用$scope.樣式名=…添加class。
·方式二:可以一次添加多個標簽,先設置值為布爾類型的$scope屬性,在標簽中添加
ng-class=”{‘red’:$scope屬性,‘green’:$scope屬性}”當對應的屬性為true時添加該樣式名。
17.自增長型id可能會因為前面的元素被刪除后之后添加的id會與前一個id沖突,所以可以通過將id設置為random來保證id不會重復。
18.不要在以數組長度為循環條件的情況下增加或刪除數組,這樣會影響循環而且很傻。
改變url的哈希值利用$location.path(“a”)在地址后面添加# /a與路由一起實現頁面局部跳轉。
19.配置路由:當請求來時用路由尋找到相應的控制器
·首先引入angular-route這個包,在創建angular對象時第二個參數依賴里填入’ngRoute’加引號??!
之后用angular對象的config(‘$routeProvider’,function($ routeProvider){
$routeProvider.when(‘/a’,{controller:對應控制器名 ,templateUrl:‘模板路徑’})
.when(‘/b’,{…} ) 利用when 來設置配置規則
.otherwise({redirect:’/a’})});
- 當請求提交時路由模塊改變的是含ng-view屬性的標簽,將其中內容替換成相應的template。
- 填入的模板路徑一定是相對于使用者的路徑而非controller的路徑。
- 填入哈希值時可以用’/student/:name?’冒號后面的被當做占位符可以任意匹配加問號表示可以為空值。在controller里注入$ routerParmas.name可以得到name匹配到的值。
使用服務模塊,對于業務邏輯都應該放入服務模塊中,創建服務模塊:
angular對象.service(“mainService”,function(){ this.函數名=function(){}})添加業務邏輯。
1.使用時先將這個模塊注入到主要的angular對象,然后將service名mainService注入到controller中。
2.過濾器:過濾器參數若是一個值則會在目標對象的全部屬性中查找匹配。
若想執行所查找的屬性則{{data|filter:{score:80}}}這樣過濾器只看對象中score屬性是否滿足條件。
使用自定函數匹配{{data|filter:函數名}}添加函數$scope.函數名=function(e){}e為現過濾對象。返回true或false。
23.在給圖片標簽的src綁定地址時要用ng-src綁定,因為如果用src瀏覽器會在angular為啟動時請求圖片。
3.用angular控制tab欄的樣式切換先使用ng-repeat來生成tab欄然后在點擊時觸發事件并根據id來改變對應欄樣式。
<li ng-repeat="list in li " ng-class='{"active":list.active}'
ng-click="activeChange(list.id)" >
使用ng-repeat時最好在后面加上track by id之類的唯一標識屬性,在下次數據更新時頁面渲染速度回加快。
4.路由最好只定義一個when(“/:參數/:參數”…)通過修改參數
$route.updataParams({參數名:參數值})來實現頁面的跳轉!!!$scope.$on("$routeChangeSuccess", function () { })來監聽地址欄的變化?。?!
還有一種可以選擇的跳轉方式就是用a標簽的href屬性,對應不同情況來選擇跳轉方式。
5.想要在angular啟動時執行某函數用$scope.init( )=function(){ }函數
6.路由的匹配也有順序,按when的照前后或者依賴注入的先后排序,先匹配上的先使用。沒有得到正確匹配一定要從路由的匹配順序上找問題!!!
7.angular中http的配置選項:
·$http({可以配置內容有method、url、data、params、transformRequest、transformResponse、cache、timeout})
·data屬性是一個對象,作為消息體的一部分發送給服務端
·params對應一個字符串或對象,若是對象則自動按照json格式序列化并追加到url后面作為發送數據的一部分
·transformRequest用于請求體頭信息和請求體進行序列化轉換,并生成一個數組發送給服務端,transformResponse則是解析服務端傳回的響應體頭信息和響應體信息。
·$http服務是只能接受一個參數的函數,這個參數是一個對象,包含了用來生成HTTP請求的配置內容。這個函數返回一個promise對象,具有success和error兩個方法。success(function(data,status,config,headers){}。
CommonJS之Promises/A規范:通過規范API接口來簡化異步編程,使我們的異步邏輯代碼更易理解。
遵循Promises/A規范的實現我們稱之為Promise對象,Promise對象有且僅有三種狀態:unfulfilled、fulfilled、failed;初始創建的時候是unfulfilled狀態,狀態只可以從unfulfilled變成fulfilled,或者unfulfilled變成failed。狀態一旦變成fulfilled或者failed,狀態就不能再變了。
Promises/A規范提供了一個在程序中描述延時(或將來)概念的解決方案,是一種處理異步編程的模式,可以有效解決回調的煩惱,并以一種同步的方式去處理業務流程。主要的思想不是執行一個方法然后阻塞應用程序等待結果返回后再回調其他方法,而是返回一個Promise對象來滿足未來監聽。fulfilled狀態和failed狀態都可以被監聽。Promise通過實現一個then接口來返回Promise對象來注冊回調:
then(fulfilledHandler, errorHandler, progressHandler);
then接口用于監聽一個Promise的不同狀態。fulfilledHandler用于監聽fulfilled狀態,errorHandler用于監聽failed狀態,progressHandler用于監聽unfulfilled狀態。Promise不強制實現unfulfilled(未完成)的事件監聽。
在$htto請求中使用promise對象并不會帶來根本上的變化,但它會減少數據加載時的白框現象或者等待加載的時間,在優化用戶體驗上將發揮明顯的作用。具體使用如下。
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中創建,在controller中使用。Angular中需要配合$q一起使用。
Promise.then( )返回的對象給下一個.then( )使用鏈式編程的方式消除了層層嵌套的麻煩,使異步變為同步。最后執行finally內的函數。then( )里面第一個匿名函數使成功時調用的方法,第二個方法是失敗時調用。
console.log(1);
//通過方法獲取promise對象
var promise=GoodListFty.testPromise();
//通過then方法觸發狀態監聽
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);
8.在控制器中注入$rootScope對象使用時面對的是頁面中的各個控制器,通過$rootScope綁定的事件在各個控制器中都會觸發生效,$scope只針對一個控制器。Angular中綁定事件調用obj.$on.(eventName,fn).
9.在angular中大部分操作之后的效果都是由$apply()方法自動在頁面中完成,如果調用了非angular中的方法和函數如setTimeout方法后需要手動調用$apply方法來改變頁面中對應的屬性值。
10.在為標簽綁定事件時可以傳入$event參數,通過event常量返回當前觸發事件的對象元素。
11.在使用插件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'}
12.包含Service,factory,Provider三個子級概念,都是返回service(父級概念)對象
三種概念定義模塊的使用場景:
·Factory:返回一個匿名對象,匿名對象中是方法的集合 return{各種方法}
·Service:在一個模塊中返回多個服務,適合用service創建模塊
·Provider:是service的底層實現,angular本身的東西,提供的服務
13.原聲JS中調用angular的$scope: 可以給$scope中添加原聲的JavaScript函數
var appElement= $('[ng-controller="myCtrl"]');
var $scope = angular.element(appElement).scope();
JSONP
由于默認angular提供的異步請求對象不支持自定義回調函數名angular隨機分配的回調函數名稱不被豆瓣支持。
所以通過service自己寫方法來獲取豆瓣上的數據。
使用時給controller注入'HttpService'通過HttpService.jsonp(url,data,callback)得到data數據。
注意:在angular中如果通過自己寫的函數或第三方的庫來調用ajax請求必須要使用$apply(‘被改變的數據’)來通知angular$scope中的某個數據被改變,需要重新渲染。$scope.$apply();可以刷新所有的數據。
(function(angular) {
// 由于默認angular提供的異步請求對象不支持自定義回調函數名
// angular隨機分配的回調函數名稱不被豆瓣支持
var http = angular.module('moviecat.services.http', []);
http.service('HttpService', ['$window', '$document', function($window, $document) {
// url : http://api.douban.com/vsdfsdf -> <script> -> html就可自動執行
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來實現異步加載庫,先引入angular-loader,因為scriptjs異步加載可能會因為有些文件小而提前加載完成,在未加載完他的依賴庫就執行導致錯誤,angular-loader會根據文件的依賴順序進行異步加載
$script([
'./bower_components/angular/angular.js',
'./bower_components/angular-route/angular-route.js',
'./app.js' // 由于這個包比較小,下載完成過后就直接執行,為保證執行順序要先引用angular-load
], function() { //庫全部加載完后執行這個回調函數
console.log(angular);
angular.bootstrap(document, ['moviecat']);
});