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
