1—$http
可以從服務器中獲取更大的數據集,這里使用angularjs的內置服務稱為$http。使用angularjs的依賴注入為phoneList組件的控制器提供服務。
在我們的控制器中使用angularjs的$http服務,向我們的web服務器發出http請求,以獲取文件中的數據。
app/phone-list/phone-list.component1.js:
angular.module('phoneList').component('phoneList',{ templateUrl:'phone-list/phone-list.template.html', controller:function PhoneListController($http){ var self = this; self.orderProp = 'age'; $http.get('phones/phones.json').then(function(response){ self.phones = response.data; }); } });
ps:$http向web服務器發出HTTP GET請求,此處URL為json文件地址。服務器通過提供json文件中的數據進行響應。(響應也可以由后端服務器動態生成)
該$http服務返回一個promise對象,其有一個方法,用來處理異步響應,並將電話數據分配給控制器,作為一個屬性。 Ps:angularjs檢測到json響應,並將其解析為傳遞給我們回調的對象的屬性。
由於phones在一個回調函數中對該屬性進行賦值,其中this沒有定義值,因此引入一個局部變量self,指向控制器實例。
Ps:要在angularjs中使用服務,只需將所需的依賴項的名稱聲明為控制器構造函數的參數:
function PhoneListController($http){…}
當構建控制器時,angularjs的依賴注入器為您的控制器提供服務。依賴注入器還負責創建服務可能具有的任何依懶性。(服務通常依賴於其他服務)。Ps: 參數名稱很重要,因為注入器使用這些進行查找依賴關系。
$http服務是一個核心的angularjs服務,通過瀏覽器的XMLHttpRequest對象或通過jsonp促進與遠程HTTP服務器的通信。$http服務是一個函數,其接收一個參數-一個配置對象-用於生成http請求並返回promise。
$http({ method: 'GET', url: '/url' }).then(function successCallback(response) { // this callback will be called asynchronously // when the response is available }, function errorCallback(response) { // called asynchronously if an error occurs // or server returns response with an error status. });
Ps:響應對象具有的屬性:數據(用於變換函數轉換的響應體)、status(響應的http狀態碼)、標題()、config(用於生成請求的配置對象)、statusText(響應的http狀態文本)、xhrStatus()
也可使用快捷方式:( $http(config); )
$http.get(‘/url’,config).then(successCallback, errorCallback); $http.post(‘/url’,data,config).then(successCallback, errorCallback); $http.head(url,[config]); $http.put(url,data,[config]); $http.delete(url,[config]); $http.jsonp(url,[config]); $http.patch(url,data,[config]);
$http服務將自動為所有請求添加特定的http頭,這些默認值可以通過訪問當前包含此默認配置的配置對象。要添加或覆蓋這些默認值,只需從這些配置對象中添加或刪除屬性即可。
要添加除post或put之外的http方法的標題,只需添加一個新的對象,以較低的http方法名稱為關鍵字,如$httpProvider.defaults.headers.get = {‘My-Header’ : ‘value’}
默認值也可以在運行時通過對象以相同的方式設置,如:
module.run(function($http){ $http.defaults.headers.common.Authorization = ‘Basic YmVlcDpib29w’ ; });
可以在headers調用時傳遞的config對象中提供一個屬性,覆蓋默認值而不在全局更改它們。
要顯示刪除根據每個請求自動添加的$httpProvider.defaults.headers標頭,請使用headers屬性,設置所需的標題為undefined:
var req = { method:'POST', url:'http://example.com', headers:{ 'Content-Type':undefined }, data:{test:'test'} } $http(req).then(function(){...},function(){...});
Ps:$前綴用於表明是angularjs的內置服務。
例子:通過獲取json文件中的數據進行頁面渲染,涉及到的文件有:index2.html、app.module.js、phone-list.template.html、phone-list.component1.js、phones.json
Index2.html:
<!DOCTYPE html> <html lang="en" ng-app="phoneList"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../angular/angular.js"></script> <script src="../scripts/app.module.js"></script> <script src="phone-list/phone-list.component1.js"></script> </head> <body> <phone-list></phone-list> </body> </html>
app.module.js:
//用來引入需要使用的module文件 //定義一個phonecatAPP模塊 var phonecatApp = angular.module('phonecatApp', []); //定義一個phoneList模塊 var phoneList = angular.module('phoneList',[]);
phone-list.template.html:
<div class="container-fluid"> <div class="row"> <div class="col-md-2"> <!--Sidebar content--> <p> Search: <input ng-model="$ctrl.query" /> </p> <p> Sort by: <select ng-model="$ctrl.orderProp"> <option value="name">Alphabetical</option> <option value="age">Newest</option> </select> </p> </div> <div class="col-md-10"> <ul class="phones"> <li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query |orderBy:$ctrl.orderProp"> <span>{{phone.name}}</span> <p>{{phone.snippet}}</p> <p>{{phone.age}}</p> </li> </ul> </div> </div> </div>
phone-list.component1.js:
angular.module('phoneList').component('phoneList',{ templateUrl:'phone-list/phone-list.template.html', controller:function PhoneListController($http){ var self = this; self.orderProp = 'age'; $http.get('phones/phones.json').then(function(response){ self.phones = response.data; }); } });
phones.json:
[ { "age":13, "id":"motorola-defy-with-motoblur", "name":"Motorola DEFY\u2122 with MOTOBLUR\u2122", "snippet":"Are you ready for everything life throws your way?" }, { "age":15, "id":"sotorola-defy-with-motoblur", "name":"Aotorola DEFY\u2122 with MOTOBLUR\u2122", "snippet":"Hi!Are you ready for everything life throws your way?" } ]
例子:獲取json文件中的數據渲染到表格中,這里涉及的文件有:mytableindex.html文件、app.module.js文件、mytable-list.template.html文件、mytable.component.js文件、tables.json文件
mytableindex.html:
<!DOCTYPE html> <html lang="en" ng-app="tableList"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../angular/angular.js"></script> <script src="../scripts/app.module.js"></script> <script src="phone-list/mytable.component.js"></script> <style> table{ border:1px solid gray; } tr{ border-top:1px solid gray; } </style> </head> <body> <table-list></table-list> </body> </html>
app.module.js:
//用來引入需要使用的module文件 //定義一個phonecatAPP模塊 var phonecatApp = angular.module('phonecatApp', []); //定義一個phoneList模塊 var phoneList = angular.module('phoneList',[]); //定義一個tableList模塊 var tableList = angular.module('tableList',[]);
mytable-list.template.html:
<div> <table> <caption>信息列表</caption> <tr> <th>序號</th> <th>公司</th> <th>聯系人</th> <th>電話</th> </tr> <tr ng-repeat="table in $ctrl.tables1"> <!--$ctrl.tables1指定模板js文件中獲取到的model--> <td>{{table.numx}}</td> <td>{{table.companyx}}</td> <td>{{table.contactx}}</td> <td>{{table.phonex}}</td> </tr> </table> </div> <!--這里模板的css樣式可以寫在主html文件的style標簽內,或者在主html文件中引入外部css文件-->
mytable.component.js:
angular.module('tableList').component('tableList',{ //這里的angular.module('tableList')也可以直接用app.module.js文件中定義的模塊tableList //在tableList模板上定義tableList組件 templateUrl:'phone-list/mytable-list.template.html', //組件用到的模板文件的URL controller:function MyTableListController($http){ //這里的controller即綁定到了組件tableList上,所以在模板中就不再需要ng指令綁定模板 var self = this; // self.orderProp = 'numx'; $http.get('phones/tables.json').then(function(response){ self.tables1 = response.data; //tables可以理解為自己指定的變量名,指代model,即json文件中的數據 }); } });
或:
angular.module('tableList').component('tableList',{ //這里的angular.module('tableList')也可以直接用app.module.js文件中定義的模塊tableList //在tableList模板上定義tableList組件 templateUrl:'phone-list/mytable-list.template.html', //組件用到的模板文件的URL controller:function MyTableListController($http){ //這里的controller即綁定到了組件tableList上,所以在模板中就不再需要ng指令綁定模板 var self = this; $http({ method: 'GET', url: 'phones/tables.json' }).then(function successCallback(response) { // this callback will be called asynchronously // when the response is available self.tables1 = response.data; }, function errorCallback(response) { // called asynchronously if an error occurs // or server returns response with an error status. return response.data; }); } });
tables.json:
[ { "numx":"1", "companyx":"創匠", "contactx":"zhajd", "phonex":"17878372837" }, { "numx":"2", "companyx":"創匠xinxi", "contactx":"zskd", "phonex":"17879072837" }, { "numx":"3", "companyx":"創匠keji", "contactx":"shdjcd", "phonex":"17870902837" }, { "numx":"4", "companyx":"創匠gs", "contactx":"djldd", "phonex":"17878372837" }, { "numx":"5", "companyx":"chuangjiang", "contactx":"ldos", "phonex":"17877896837" }, { "numx":"6", "companyx":"chjdkj", "contactx":"zdljd", "phonex":"17878567837" } ]
例子:將數據渲染到表格中
<!DOCTYPE html> <html lang="en" ng-app="exampApp"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../angular/angular.js"></script> <style> table{ border:1px solid gray; } td{ border-top:1px solid gray; /*border-bottom:1px solid gray;*/ } </style> </head> <body> <div> <table ng-controller="exampListController"> <tr> <th>序號</th> <th>公司</th> <th>聯系人</th> <th>電話</th> </tr> <tr ng-repeat="item in data"> <td>{{item.numx}}</td> <td>{{item.companyx}}</td> <td>{{item.contactx}}</td> <td>{{item.phonex}}</td> </tr> </table> </div> <script> var exampApp = angular.module('exampApp',[]); exampApp.controller('exampListController',function exampListController($scope){ $scope.data = [ { "numx":"1", "companyx":"創匠", "contactx":"zhajd", "phonex":"17878372837" }, { "numx":"2", "companyx":"創匠xinxi", "contactx":"zskd", "phonex":"17879072837" }, { "numx":"3", "companyx":"創匠keji", "contactx":"shdjcd", "phonex":"17870902837" }, { "numx":"4", "companyx":"創匠gs", "contactx":"djldd", "phonex":"17878372837" }, { "numx":"5", "companyx":"chuangjiang", "contactx":"ldos", "phonex":"17877896837" }, { "numx":"6", "companyx":"chjdkj", "contactx":"zdljd", "phonex":"17878567837" } ]; }); </script> </body> </html>
路由:
組件允許我們以模塊化、可測試的方式將控制器與模板相結合,我們將使用組件進行路由,每個路由將與一個組件相關聯,該組件將負責提供視圖模板和控制器。
angular-route.js:定義angularjs的ngRoute模塊,為我們提供路由。
app.config.js:配置提供給我們的主模塊。
Phone-detail.module.js:定義包含phoneDetail組件的新模塊。
Phone-detail.component.js:定義一個虛擬phoneDetail組件。
依賴注入:
依賴注入是angularjs的核心,需要了解其工作原理!
當應用程序引導時,angularjs創建一個注入器,用於查找和注入應用程序所需的所有服務。注射器僅執行以下步驟:加載您在應用程序中指定的模塊定義;注冊在這些模塊中定義的所有提供商;當被要求這樣做時,通過其提供商將服務及其依賴關系實例化為可注射功能的參數。提供商是提供(創建)服務實例並公開配置API的對象,可用於控制服務的創建和運行時行為。在$route服務的情況下,$routeProvider公開的API允許你為應用程序定義路由。
提供者($provide):該$provice服務負責告訴angular如何創建新的可注射的東西,這些東西叫服務,即$provide服務告訴angular如何創建服務。服務由所謂的提供商定義,這是在使用時創建的$provide。通過服務provider方法定義提供者$provide,$provide將其注入到應用程序的config功能中獲得服務。
myMod.config(function($provide){ $provide.provider('greeting',function(){ this.$get = function(){ return function(name){ alert("hello" + name); }; }; }); });
ps:這里定義了名為greeting的新的提供商作為服務,我們可以注入一個名為greeting的變量可以注射到任何一個可注射的函數中,如控制器,angular將調用提供者的$get函數來返回一個新的服務實例。在和這種情況下,要注入的東西是一個基於name參數和alert消息的函數。我們可以這樣使用:
myMod.controller("MainController",function($scope,greeting){ $scope.onClick = function(){ greeting("Ford Prefect"); } })
service、factory、value都只是定義提供者的各個部分的快捷方式,即它們提供了一種定義提供者的方法,而不必輸入所有的東西:
myMod.config(function($provide){ $provide.factory('greeting',function(){ return function(name){ alert("hello, " + name); }; }); });
greeting服務總是返回相同的功能,因此可以使用value來定義:
myMod.config(function($provide){ $provide.value('greeting',function(name){ alert("hello, " + name); }); });
var myMod = angular.module('myModule',[]); myMod.provider('greeting',...); myMod.factory('greeting',...); myMod.service('greeting',...); myMod.value('greeting',...); myMod.provider('greeting',function(){ this.$get = function(){ return function(name){ alert("hello, " + name); }; }; });
myMod.factory('greeting',function(){ return function(name){ alert("hello, " + name); }; });
myMod.service('greeting',function(){ return function(name){ alert("hello, " + name); }; });
myMod.value('greeting',function(name){ alert("hello, " + name); });
注射器($injector):負責使用我們提供的代碼$provide實際創建我們的服務實例。有了$injector,則可以使用服務get名稱調用定義的服務實例。注射器還負責將服務注入功能。每一個angularjs應用程序都有一個$injector,當應用程序啟動時它將被創建,可以通過注入$injector注入到任何一個可注射的函數。
一旦有了$injector,通過調用服務的get方法,可以得到一個已定義好的服務的實例
var greeting = $injector.get('greeting'); greeting('Ford Prefect');
注射器還負責將服務注入到函數中:
var myFunction = function(greeting){ greeting('Ford Prefect'); }; $injector.invoke(myFunction);
配置提供商:
提供者允許大量的配置。當通過provider或angularjs提供的快捷方式創建一個服務時,就創建了一個provider,它定義了服務是如何創建的。這些providers可以注入到你的應用程序的config部分,便於交互。
Angular運行你的程序主要有兩階段:config、run;config階段可以根據需要設置任何提供商的地方,這也是設置指令、控制器、過濾器等的地方,run階段是angular實際編譯DOM並啟動應用程序的地方。可以使用myMod.config和myMod.run函數添加在這些階段中運行的其他代碼。在config階段,只有供應商可以注射。
控制器($controller):可以將東西注入到控制器中,但不能將控制器注入到事件中。
過濾器(filter)和指令(directive):
將core模塊注冊為主phonecatApp模塊的依賴關系:
angular.module('phonecatApp', [ ... 'core', ... ]);
ps:可能稍微有點凌亂,還請見諒。所謂好記性不如爛筆頭,這是選擇寫博客的初衷,希望通過整理能夠讓自己更深入理解,以后不清楚的地方還可以回來看看。同時,放在這種公共的地方,也希望能夠給一些人一丁點的參考,至少我從網上獲得了很多。此外,也期待描述的不妥的地方,有小伙伴可以指出,然后改進,進步。(8-17)
參考 & 感謝:https://docs.angularjs.org