aboutsummaryrefslogtreecommitdiffstats
path: root/src/Angular.js
diff options
context:
space:
mode:
authorVojta Jina2010-11-17 00:31:40 +0000
committerIgor Minar2010-11-25 08:51:26 -0800
commit47f159cdf319bb9b7ce25228aa50cbb87fbf242f (patch)
tree378c17c02b37d888b9c0cfb2344a2a01f4d28618 /src/Angular.js
parent99eb123d791395d2fe88a6171e125cb0bd567ddf (diff)
downloadangular.js-47f159cdf319bb9b7ce25228aa50cbb87fbf242f.tar.bz2
Doc service: added example into service overview
Diffstat (limited to 'src/Angular.js')
-rw-r--r--src/Angular.js134
1 files changed, 124 insertions, 10 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 540095bf..4d3c360f 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -525,16 +525,17 @@ var _undefined = undefined,
* Each service could have dependencies (other services), which are passed in constructor.
* Because JS is dynamicaly typed language, dependency injection can not use static types
* to satisfy these dependencies, so each service must explicitely define its dependencies.
- * This is done by $inject property.
+ * This is done by `$inject` property.
*
* For now, life time of all services is the same as the life time of page.
*
*
- * # Standard services
+ * # Built-in services
* The Angular framework provides a standard set of services for common operations.
* You can write your own services and rewrite these standard services as well.
- * Like other core angular variables, standard services always start with $.
- *
+ * Like other core angular variables, the built-in services always start with $.
+ *
+ * * `angular.service.$browser`
* * `angular.service.$window`
* * `angular.service.$document`
* * `angular.service.$location`
@@ -551,15 +552,128 @@ var _undefined = undefined,
* * `angular.service.$cookies`
* * `angular.service.$cookieStore`
*
- * # Writing your own services
+ * # Writing your own custom services
+ * Angular provides only set of basic services, so you will probably need to write your custom
+ * service very soon. To do so, you need to write a factory function and register this function
+ * to angular's dependency injector. This factory function must return an object - your service
+ * (it is not called with new operator).
+ *
+ * **angular.service** has three parameters:
+ *
+ * - `{string} name` - Name of the service
+ * - `{function()} factory` - Factory function (called just once by DI)
+ * - `{Object} config` - Hash of configuration (`$inject`, `$creation`)
+ *
+ * If your service requires - depends on other services, you need to specify them
+ * in config hash - property $inject. This property is an array of strings (service names).
+ * These dependencies will be passed as parameters to the factory function by DI.
+ * This approach is very useful when testing, as you can inject mocks/stubs/dummies.
+ *
+ * Here is an example of very simple service. This service requires $window service (it's
+ * passed as a parameter to factory function) and it's just a function.
+ *
+ * This service simple stores all notifications and after third one, it displays all of them by
+ * window alert.
* <pre>
- * angular.service('notify', function(location) {
- * this.one = function() {
- * }
- * }, {$inject: ['$location']});
+ angular.service('notify', function(win) {
+ var msgs = [];
+ return function(msg) {
+ msgs.push(msg);
+ if (msgs.length == 3) {
+ win.alert(msgs.join("\n"));
+ msgs = [];
+ }
+ };
+ }, {$inject: ['$window']});
* </pre>
+ *
+ * And here is a unit test for this service. We use Jasmine spy (mock) instead of real browser's alert.
+ * <pre>
+ * var mock, notify;
+ *
+ * beforeEach(function() {
+ * mock = {alert: jasmine.createSpy()};
+ * notify = angular.service('notify')(mock);
+ * });
+ *
+ * it('should not alert first two notifications', function() {
+ * notify('one');
+ * notify('two');
+ * expect(mock.alert).not.toHaveBeenCalled();
+ * });
+ *
+ * it('should alert all after third notification', function() {
+ * notify('one');
+ * notify('two');
+ * notify('three');
+ * expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree");
+ * });
+ *
+ * it('should clear messages after alert', function() {
+ * notify('one');
+ * notify('two');
+ * notify('third');
+ * notify('more');
+ * notify('two');
+ * notify('third');
+ * expect(mock.alert.callCount).toEqual(2);
+ * expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
+ * });
+ * </pre>
+ *
+ * # Injecting services into controllers
+ * Using services in a controllers is very similar to using service in other service.
+ * Again, we will use dependency injection.
+ *
+ * JavaScript is dynamic language, so DI is not able to figure out which services to inject by
+ * static types (like in static typed languages). Therefore you must specify the service name
+ * by the `$inject` property - it's an array that contains strings with names of services to be
+ * injected. The name must match the id that service has been registered as with angular.
+ * The order of the services in the array matters, because this order will be used when calling
+ * the factory function with injected parameters. The names of parameters in factory function
+ * don't matter, but by convention they match the service ids.
+ * <pre>
+ * function myController($loc, $log) {
+ * this.firstMethod = function() {
+ * // use $location service
+ * $loc.setHash();
+ * };
+ * this.secondMethod = function() {
+ * // use $log service
+ * $log.info('...');
+ * };
+ * }
+ * // which services to inject ?
+ * myController.$inject = ['$location', '$log'];
+ * </pre>
+ *
+ * @example
+ * <script type="text/javascript">
+ * angular.service('notify', function(win) {
+ * var msgs = [];
+ * return function(msg) {
+ * msgs.push(msg);
+ * if (msgs.length == 3) {
+ * win.alert(msgs.join("\n"));
+ * msgs = [];
+ * }
+ * };
+ * }, {$inject: ['$window']});
+ *
+ * function myController(notifyService) {
+ * this.callNotify = function(msg) {
+ * notifyService(msg);
+ * };
+ * }
+ *
+ * myController.$inject = ['notify'];
+ * </script>
*
- * # Using services in controller
+ * <div ng:controller="myController">
+ * <p>Let's try this simple notify service, injected into the controller...</p>
+ * <input ng:init="message='test'" type="text" name="message" />
+ * <button ng:click="callNotify(message);">NOTIFY</button>
+ * </div>
*/
angularService = extensionMap(angular, 'service'),
angularCallbacks = extensionMap(angular, 'callbacks'),