angularJS 系列(三)- 自定义 Service
参考:http://viralpatel.net/blogs/angularjs-service-factory-tutorial/
https://www.pluralsight.com/blog/tutorials/angularjs-step-by-step-services
想法:定义一个 angular module 之后呢, 在许多的 controller 中会有一些公共的函数,或者是说在很多controller 中都要使用到的共同的方法,类似的逻辑其实是可以提取出来,进行封装。
这样,就抽象出来了 service 这样一个概念。
来继续深入理解一下,
1、到底什么是 service 呢?(what is a service ?)
抽象出来的service 是无状态的,将一些种类的方法封装成一个对象。
The type of service I'm talking about is typically stateless and encapsulates some sort of functionality。
2、为什么需要 service 呢?(why we need services ?)
In my previous post about AngularJS controllers, I spoke a bit about the need for separation of concerns in modern-day JavaScript applications, which are much more involved than those of a decade ago. With the amount of JavaScript needed in a modern-day application, the architecture of your JavaScript takes on much more importance. Two of the five SOLID principles of object oriented design are directly related to Services: the Single Responsibility Principle (SRP) and the Dependency Inversion Principle (DIP).
The single responsibility principle teaches that every object should have a single responsibility. If we use the example of a controller, it's responsibility is essentially to wire up the scope (which holds your models) to your view; it is essentially the bridge between your models and your views. If your controller is also responsible for making ajax calls to fetch and update data, this is a violation of the SRP principle. Logic like that (and other business logic) should instead be abstracted out into a separate service, then injected into the objects that need to use it.
This is where the Dependency Inversion Principle comes in. The DIP states that objects should depend on abstractions, not concretions. In languages like C# and Java, this means your objects depend on Interfaces instead of Classes. In JavaScript you could look at any parameter of any function (constructor function or otherwise) as an abstraction, since you can pass in any object for that parameter so long as it has the members on it that are used within that method. But the key here is the ability to use dependency injection - the ability to inject into other objects. This means that all of your controllers, directives, filters and other services should take in any external dependencies as parameters during construction. This allows you to have loosely coupled code and has the added benefit of making unit testing much easier.
Use factory
if object definition syntax is preferable
1 2 3 4 5 6 | app.factory( 'factory' , function () { ... return { value: '...' }; }); |
or it returns something that is not an object for some reason.
Use service
if this
syntax is preferable
1 2 3 | app.service( 'service' , function () { this .value = '...' ; }); |
or it should return an object created with new
from another constructor, e.g.
1 2 3 | app.factory( 'factory' , function () { return new someConstructor(); }); |
VS
1 | app.service( 'service' , someConstructor); |
A good use case for service
is that you can seamlessly refactor existing controllers with controllerAs
syntax to inherit from common service, in this case no this
statements replacement is required, as shown here:
1 2 3 4 5 6 7 8 9 10 11 12 | app.service( 'parentControllerService' , function () { this .value = '...' ; }); app.controller( 'MainController' , function (parentControllerService) { angular.extend( this , parentControllerService); }); app.controller( 'ChildController' , function (parentControllerService) { angular.extend( this , parentControllerService); this .value = '!!!' ; }); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现