在AngularJS中出于内存占用和性能的考虑,控制器只会在需要时被实例化,并且不再需要就会被销毁。这意味着每次切换路由或重新加载视图时,当前的控制器会被AngularJS清除掉。做为一个SPA应用,有时我们希望能够在路由更新后仍能保留前一个页面的部分数据,这时我们可能的做法是将需要保留的数据放置到$rootScope中或者放到Cathe中,这样做并非最好的方式,下面来看一种更具扩展性、更方便的方式即service。
服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性。服务是一个单例对象,在每个应用中只会被实例化一次(被 $injector实例化) ,并且是延迟加载的(需要时才会被创建) 。服务提供了把与特定功能相关联的方法集中在一起的接口。
以AngularJS的 $http 服务为例,它提供了对浏览器的 XMLHttpRequest 对象的底层访问功能,我们可以通过 $http 的API同XMLHttpRequest 进行交互,而不需要因为调用这些底层代码而污染应用。
创建自定义服务
下面创建一个简单的服务,用于从后台的Controller中获取文章列表数据,同时我们给我们的给这个文章列表提供一个标题,这是一个比较典型的示例,服务提供了一个获取数据的方法(getArticle)和一个属性(title)。
var articleService = angular.module('articleService', []);
articleService.factory('articleService',['$http',
function($http) {
vardoRequest = function () {
return$http({
method: 'GET',
url: '/article/getallarticle'
});
}
return{
title:'我的第一个服务',
getArticle: function () {
return doRequest();
}
};
}
]);
在这个示例中采用的是以工厂模式创建一个服务,当然也可以采用service模式进行创建,服务需要提供返回值供外部使用。上面的示例中使用$http服务从后台调取数据,来看看后台的数据是如何:
public classArticleController :Controller
{
//
//GET: /Article/
publicActionResult getAllArticle()
{
List<ArticleModel>articles =new List<ArticleModel>();
articles.Add(new ArticleModel(){ Title = "我的文章1", Content ="内容很经常啊11111", Auther="开开", Created =DateTime.Now});
articles.Add(new ArticleModel(){ Title = "我的文章2", Content ="内容很经常啊22222", Auther="开开", Created =DateTime.Now});
articles.Add(new ArticleModel(){ Title = "我的文章3", Content ="内容很经常啊33333", Auther="开开", Created =DateTime.Now});
articles.Add(new ArticleModel(){ Title = "我的文章4", Content ="内容很经常啊44444", Auther="开开", Created =DateTime.Now});
returnJson(articles,JsonRequestBehavior.AllowGet);
}
}
视图调用
<div class="col-md-9" id="article" ng-controller="articleCtrl">
<h1>{{serviceName}}</h1>
<dl ng-repeat="title in artices">
<dt>{{$index+1}}、{{title.Title}}</dt>
<dd>{{title.Content}}</dd>
</dl>
</div>
这个Controller是我们后端的Controller,这个概念要分清,AngularJS是前端开发框架,采用了MVC模式,而我们整个应用也是一个MVC模式开发,后台采用的是asp.net的MVC模式,前端和后端都采用的MVC模式,但两者直接并非相等。在这个示例中我们是使用了一部分模拟数据,真实环境下就会使用EF为Controller提供数据。
使用自定义服务
上面定义了一个服务,下面看看在Controller中如何使用这个服务
var articleApp = angular.module('articleApp', ['articleService']);
articleApp.controller('articleCtrl',['$scope', 'articleService',
function($scope, articleService) {
articleService.getArticle().success(function(data, status) {
$scope.artices = data;
});
$scope.serviceName = articleService.title;
}
]);
这里看出articleCtrl这个controller在构造时注入了articleService这个服务,同angularJS内置的服务使用方法一样,我们将这个服务获取的数据保存到$scope中为视图提供数据
在AngularJS应用中, factory() 方法是用来注册服务的最常规方式,同时还有其他一些API
可以在特定情况下帮助我们减少代码量。
共有5种方法用来创建服务:
factory()
service()
constant()
value()
provider()
通过创建自定义服务是对Controller进行扩展的最佳方式,服务可以切分成很多碎片,然后在Controller中对这些碎片进行组合,这样就能很轻松实现扩展。