AngularJS之Service(四)
前言
前面我们讲了控制器、过滤器以及指令,这一节我们来讲讲重大内容之一服务和其中涉及到的工厂。
话题
AngularJS中服务可以说是和DI紧密联系在一起,在应用程序中我们可以通过使用服务来共享代码,服务可以被延迟实例化,为何这样说,在Angular内置的服务或者我们自定义的服务只有在注入才能被实例化,同时也就意味着当我们应用程序需要依赖于服务这一组件时才会被实例化,Angular中的服务是一个单例对象即服务中的某一个部分依赖于另外一个服务都会返回从服务工厂中获取到单个实例的引用。Angular中有许多内置默认有用的服务供我们使用,和过滤器一样,我们同样可以根据需求自定义服务。
服务到底做了什么?它的底层实现了什么?它提供了跨领域、请求和操作数据、和外部服务集成以及包括业务逻辑的功能,它简单的就如一个JSON对象。下图给出了Angular组件以及它们之间的作用。
服务到底什么时候应该被创建?为什么要被创建?当我们在应用程序利用Angular需要重用代码时,我们通过服务来封装功能,在Angular模块中有三种方法来定义服务:Factory、Service、Provider。下面我们就这三种方式来创建服务。
Factory method for creating service(推荐方式)
创建服务最简单的方式则是通过module.Factory的方式来创建服务,通过传递两个参数,一个是创建服务的名称,另外一个则是factory函数来返回服务对象。下面我们来创建一个日志记录服务看看。
FactoryService.js
创建factoryApp模块并自定义一个logService服务。
var factroyApp = angular.module('factoryApp', []); factroyApp.factory('logService', function(){ var messageCount = 0; return { log : function(msg){ console.log("(日志提醒 + " + messageCount++ + ") " + msg); } }; })
app.js
加载factoryApp依赖模块,通过点击对应的按钮来记录该按钮的文本以及点击的次数。
var app = angular.module('myApp', ['factoryApp']); app.controller('FactoryController', function ($scope, logService) { $scope.data = { device: ["Vivo Xplay5", "OPPO R9", "Huawei P9"], totalClicks: 0 }; $scope.$watch('data.totalClicks', function (count) { logService.log("点击次数: " + count); }); }); app.directive("triButton", function (logService) { return { scope: { counter: "=counter" }, link: function (scope, element, attrs) { element.on("click", function (event) { logService.log("所点击按钮文本为: " + event.target.innerText); scope.$apply(function () { scope.counter++; }); }); } } });
FactoryHtml
<html ng-app="myApp"> <head> <meta charset="utf-8"> <title></title> <link href="../Content/bootstrap.min.css" rel="stylesheet"/> <script type="text/javascript" src="../Scripts/angular.min.js"></script> <script type="text/javascript" src="../Service/FactoryService.js"></script> <script type="text/javascript" src="../app.js"></script> </head> <body ng-controller="FactoryController"> <div class="well"> <div class="btn-group" tri-button counter="data.totalClicks" source="data.device"> <button class="btn btn-default" ng-repeat="item in data.device"> {{item}} </button> </div> <h5>总点击次数: {{data.totalClicks}}</h5> </div> </body> </html>
我们同样来看看结果:
其实对于上述app.js我们完全可以进行改造,通过DI来实现(虽然还未讲到DI)我们可以事先体验一下来得到同样的效果,同时将上述控制器代码进行拆分,这样代码才能一目了然。将app.js中控制器代码改造如下:
app.controller('FactoryController',FactoryController); app.$inject = ['$scope','logService']; function FactoryController($scope,logService){ $scope.data = { device: ["Vivo Xplay5", "OPPO R9", "Huawei P9"], totalClicks: 0 }; $scope.$watch('data.totalClicks', function (count) { logService.log("点击次数: " + count); }); }
Service method for creating service
我们同样可以用service方法来创建服务,但是与上述通过工厂方法来创建服务有点不同,当在AnuglarJS中某一组件需要通过工厂方法定义的服务这一依赖时,很简单只是通过工厂方法返回的对象来使用该对象即可,而在service方法中需要使用服务对象,那么需要将工厂方法作为一个构造函数并且需要使用js关键字来创建这个服务对象,此时这个关键字则不会再在程序中大量使用,则容易造成不必要的麻烦。说了这么多貌似只有用代码才能加深我们的理解,其实就是利用原型继承来创建,我们重新写一个日志服务方法。
上述我们只需要将创建服务的脚本进行改造如下即可:
var serviceApp = angular.module('factoryApp', []); var baseLogger = function () { var messageCount = 0; this.log = function (msg) { console.log("(日志提醒 + " + messageCount++ + ") " + msg); } }; var debugLogger = function () { }; debugLogger.prototype = new baseLogger serviceApp.service("logService", debugLogger);
上述代码想必不用做过多解释,再加上第一种方式作为推荐方式,这两种方式作为了解,知道有这三种方式即可。
Provider method for creating service
对于通过这种方式来创建服务我们需要更多的去用代码进行改造,和第一种方式类比,我们通过工厂函数来返回,而对于此方法我们最终需要通过调用$get方法来获取服务对象。代码如下:
var providerApp = angular.module('factoryApp', []); providerApp.provider("logService", function () { var messageCount = 0; return { $get: function () { return { log: function (msg) { console.log("(日志提醒 + " + messageCount++ + ") " + msg); } }; } } });
总结
这一节我们稍微比较详细的介绍了在AngularJS中如何创建服务,利用三种方式来创建服务,希望对阅读本文的你有所帮助,我们下节再叙。

为了方便大家在移动端也能看到我分享的博文,现已注册个人公众号,扫描上方左边二维码即可,欢迎大家关注,有时间会及时分享相关技术博文。
感谢花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让楼主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/CreateMyself)/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构