|
1 | 1 | @workInProgress |
2 | 2 | @ngdoc overview |
3 | 3 | @name angular.service |
4 | | - |
5 | 4 | @description |
6 | | -# Overview |
7 | | -Services are substituable objects, which are wired together using dependency injection (DI). |
8 | | -Each service could have dependencies (other services), which are passed in constructor. |
9 | | -Because JS is dynamicaly typed language, dependency injection can not use static types |
10 | | -to identify these dependencies, so each service must explicitely define its dependencies. |
11 | | -This is done by `$inject` property. |
12 | | - |
13 | | - |
14 | | -# Built-in services |
15 | | -angular provides a set of services for common operations. These services can be overriden by custom |
16 | | -services if needed. |
17 | | - |
18 | | -Like other core angular variables and identifiers, the built-in services always start with `$`. |
19 | | - |
20 | | - * {@link angular.service.$browser $browser} |
21 | | - * {@link angular.service.$window $window} |
22 | | - * {@link angular.service.$document $document} |
23 | | - * {@link angular.service.$location $location} |
24 | | - * {@link angular.service.$log $log} |
25 | | - * {@link angular.service.$exceptionHandler $exceptionHandler} |
26 | | - * {@link angular.service.$hover $hover} |
27 | | - * {@link angular.service.$invalidWidgets $invalidWidgets} |
28 | | - * {@link angular.service.$route $route} |
29 | | - * {@link angular.service.$xhr $xhr} |
30 | | - * {@link angular.service.$xhr.error $xhr.error} |
31 | | - * {@link angular.service.$xhr.bulk $xhr.bulk} |
32 | | - * {@link angular.service.$xhr.cache $xhr.cache} |
33 | | - * {@link angular.service.$resource $resource} |
34 | | - * {@link angular.service.$cookies $cookies} |
35 | | - * {@link angular.service.$cookieStore $cookieStore} |
36 | | - |
37 | | -# Writing your own custom services |
38 | | -angular provides only set of basic services, so for any nontrivial application it will be necessary |
39 | | -to write one or more custom services. To do so, a factory function that creates a services needs to |
40 | | -be registered with angular's dependency injector. This factory function must return an object - the |
41 | | -service (it is not called with the `new` operator). |
42 | | - |
43 | | -**angular.service** accepts three parameters: |
44 | | - |
45 | | - - `{string} name` - Name of the service. |
46 | | - - `{function()} factory` - Factory function (called just once by DI). |
47 | | - - `{Object} config` - Configuration object with following properties: |
48 | | - - `$inject` - {Array.<string>} - Array of service ids that this service depends on. These |
49 | | - services will be passed as arguments into the factory function in the same order as specified |
50 | | - in the `$inject` array. Defaults to `[]`. |
51 | | - - `$eager` - {boolean} - If true, the service factory will be called and thus, the service will |
52 | | - be instantiated when angular boots. If false, service will be lazily instantiated when it is |
53 | | - first requested during instantiation of a dependant. Defaults to `false`. |
54 | | - |
55 | | -The `this` of the factory function is bound to the root scope of the angular application. |
56 | | - |
57 | | -angular enables services to participate in dependency injection (DI) by registering themselves with |
58 | | -angular's DI system (injector) under a `name` (id) as well as by declaring dependencies which need |
59 | | -to be provided for the factory function of the registered service. The ability to swap dependencies |
60 | | -for mocks/stubs/dummies in tests allows for services to be highly testable. |
61 | | - |
62 | | -Here is an example of very simple service. This service requires $window service (it's |
63 | | -passed as a parameter to factory function) and it's just a function. |
64 | | - |
65 | | -This service simple stores all notifications and after third one, it displays all of them by |
66 | | -window alert. |
67 | | -<pre> |
68 | | - angular.service('notify', function(win) { |
69 | | - var msgs = []; |
70 | | - return function(msg) { |
71 | | - msgs.push(msg); |
72 | | - if (msgs.length == 3) { |
73 | | - win.alert(msgs.join("\n")); |
74 | | - msgs = []; |
75 | | - } |
76 | | - }; |
77 | | - }, {$inject: ['$window']}); |
78 | | -</pre> |
79 | | - |
80 | | -And here is a unit test for this service. We use Jasmine spy (mock) instead of real browser's alert. |
81 | | -<pre> |
82 | | -var mock, notify; |
83 | | - |
84 | | -beforeEach(function() { |
85 | | - mock = {alert: jasmine.createSpy()}; |
86 | | - notify = angular.service('notify')(mock); |
87 | | -}); |
88 | | - |
89 | | -it('should not alert first two notifications', function() { |
90 | | - notify('one'); |
91 | | - notify('two'); |
92 | | - expect(mock.alert).not.toHaveBeenCalled(); |
93 | | -}); |
94 | | - |
95 | | -it('should alert all after third notification', function() { |
96 | | - notify('one'); |
97 | | - notify('two'); |
98 | | - notify('three'); |
99 | | - expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree"); |
100 | | -}); |
101 | | - |
102 | | -it('should clear messages after alert', function() { |
103 | | - notify('one'); |
104 | | - notify('two'); |
105 | | - notify('third'); |
106 | | - notify('more'); |
107 | | - notify('two'); |
108 | | - notify('third'); |
109 | | - expect(mock.alert.callCount).toEqual(2); |
110 | | - expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]); |
111 | | -}); |
112 | | -</pre> |
113 | | - |
114 | | -# Injecting services into controllers |
115 | | -Using services as dependencies for controllers is very similar to using them as dependencies for |
116 | | -another service. |
117 | | - |
118 | | -JavaScript is dynamic language, so DI is not able to figure out which services to inject by |
119 | | -static types (like in static typed languages). Therefore you must specify the service name |
120 | | -by the `$inject` property - it's an array that contains strings with names of services to be |
121 | | -injected. The name must match the id that service has been registered as with angular. |
122 | | -The order of the services in the array matters, because this order will be used when calling |
123 | | -the factory function with injected parameters. The names of parameters in factory function |
124 | | -don't matter, but by convention they match the service ids. |
125 | | -<pre> |
126 | | -function myController($loc, $log) { |
127 | | - this.firstMethod = function() { |
128 | | - // use $location service |
129 | | - $loc.setHash(); |
130 | | - }; |
131 | | - this.secondMethod = function() { |
132 | | - // use $log service |
133 | | - $log.info('...'); |
134 | | - }; |
135 | | -} |
136 | | -// which services to inject ? |
137 | | -myController.$inject = ['$location', '$log']; |
138 | | -</pre> |
139 | | - |
140 | | -@example |
141 | | -<doc:example> |
142 | | - <doc:source> |
143 | | - <script type="text/javascript"> |
144 | | - angular.service('notify', function(win) { |
145 | | - var msgs = []; |
146 | | - return function(msg) { |
147 | | - msgs.push(msg); |
148 | | - if (msgs.length == 3) { |
149 | | - win.alert(msgs.join("\n")); |
150 | | - msgs = []; |
151 | | - } |
152 | | - }; |
153 | | - }, {$inject: ['$window']}); |
154 | | - |
155 | | - function myController(notifyService) { |
156 | | - this.callNotify = function(msg) { |
157 | | - notifyService(msg); |
158 | | - }; |
159 | | - } |
160 | 5 |
|
161 | | - myController.$inject = ['notify']; |
162 | | - </script> |
163 | 6 |
|
164 | | - <div ng:controller="myController"> |
165 | | - <p>Let's try this simple notify service, injected into the controller...</p> |
166 | | - <input ng:init="message='test'" type="text" name="message" /> |
167 | | - <button ng:click="callNotify(message);">NOTIFY</button> |
168 | | - </div> |
169 | | - </doc:source> |
170 | | - <doc:scenario> |
171 | | - it('should test service', function(){ |
172 | | - expect(element(':input[name=message]').val()).toEqual('test'); |
173 | | - }); |
174 | | - </doc:scenario> |
175 | | -</doc:example> |
| 7 | +The services API provides objects for carrying out common web app tasks. Service objects are |
| 8 | +managed by angular's {@link guide/dev_guide.di dependency injection system}. |
| 9 | + |
| 10 | + |
| 11 | +* {@link angular.service.$browser $browser } - Provides an instance of a browser object |
| 12 | +* {@link angular.service.$cookieStore $cookieStore } - Provides key / value storage backed by |
| 13 | +session cookies |
| 14 | +* {@link angular.service.$cookies $cookies } - Provides read / write access to browser cookies |
| 15 | +* {@link angular.service.$defer $defer } - Defers function execution and try / catch block |
| 16 | +* {@link angular.service.$document $document } - Provides reference to `window.document` element |
| 17 | +* {@link angular.service.$exceptionHandler $exceptionHandler } - Receives uncaught angular |
| 18 | +exceptions |
| 19 | +* {@link angular.service.$hover $hover } - |
| 20 | +* {@link angular.service.$invalidWidgets $invalidWidgets } - Holds references to invalid widgets |
| 21 | +* {@link angular.service.$location $location } - Parses the browser location URL |
| 22 | +* {@link angular.service.$log $log } - Provides logging service |
| 23 | +* {@link angular.service.$resource $resource } - Creates objects for interacting with RESTful |
| 24 | +server-side data sources |
| 25 | +* {@link angular.service.$route $route } - Provides deep-linking services |
| 26 | +* {@link angular.service.$updateView $updateView } - Queues view updates |
| 27 | +* {@link angular.service.$window $window } - References the browsers `window` object |
| 28 | +* {@link angular.service.$xhr $xhr} - Generates an XHR request. |
| 29 | + |
| 30 | + |
| 31 | +For information on how angular services work and how to write your own services, see {@link |
| 32 | +guide/dev_guide.services Angular Services} in the angular Developer Guide. |
0 commit comments