diff options
| author | Vojta Jina | 2010-11-17 00:31:40 +0000 | 
|---|---|---|
| committer | Igor Minar | 2010-11-25 08:51:26 -0800 | 
| commit | 47f159cdf319bb9b7ce25228aa50cbb87fbf242f (patch) | |
| tree | 378c17c02b37d888b9c0cfb2344a2a01f4d28618 /src/Angular.js | |
| parent | 99eb123d791395d2fe88a6171e125cb0bd567ddf (diff) | |
| download | angular.js-47f159cdf319bb9b7ce25228aa50cbb87fbf242f.tar.bz2 | |
Doc service: added example into service overview
Diffstat (limited to 'src/Angular.js')
| -rw-r--r-- | src/Angular.js | 134 | 
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'),  | 
