angularjs学习笔记--$http、数据渲染到表格、路由、依赖注入、provider

 

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

 

posted @ 2017-08-19 10:18  安静的嘶吼  阅读(1828)  评论(0编辑  收藏  举报