diff options
| author | Igor Minar | 2012-01-15 23:28:10 -0800 |
|---|---|---|
| committer | Igor Minar | 2012-01-17 09:49:37 -0800 |
| commit | 92af30ce6e99676c71c85bd08962b68629564908 (patch) | |
| tree | 4adf4b56cbf7c9fb6ee9dee8f40dd16fb2199842 /docs/content/guide | |
| parent | 54581d36df74ac128a078aafb3e4b66e0b1599f3 (diff) | |
| download | angular.js-92af30ce6e99676c71c85bd08962b68629564908.tar.bz2 | |
docs(*): various doc fixes
Diffstat (limited to 'docs/content/guide')
12 files changed, 168 insertions, 157 deletions
diff --git a/docs/content/guide/dev_guide.di.understanding_di.ngdoc b/docs/content/guide/dev_guide.di.understanding_di.ngdoc index e9ee6abf..e4955ae0 100644 --- a/docs/content/guide/dev_guide.di.understanding_di.ngdoc +++ b/docs/content/guide/dev_guide.di.understanding_di.ngdoc @@ -7,11 +7,11 @@ While DI is widely used in statically typed languages such as Java or C++, it ha used in JavaScript. Angular brings the benefits of DI into JavaScript apps. In angular, DI is implemented as a subsystem that manages dependencies between services, -controllers, widgets, and filters. The most important of these are {@link api/angular.module.ng -services}. +controllers, widgets, and filters. -Services are objects that handle common tasks in web applications. Angular provides several{@link -api/angular.module.ng built-in services}, and you can create your own custom services. +Services are objects that handle common tasks in web applications. Angular provides several {@link +api/angular.module.ng built-in services}, and you can create your +{@link dev_guide.services.creating_services own custom services}. The main job of angular's DI subsystem is to provide services to angular components that depend on them. The way the DI subsystem provides services is as follows: all services are registered with @@ -38,21 +38,9 @@ factory function from the service factory repository to construct it. ## How Scope Relates to DI -The {@link api/angular.injector injector} is responsible for resolving the service dependencies in -the application. It gets created and configured with the creation of a root scope. The injector -caches instances of services, with the services cache bound to the root scope. +The root scope of the application is just a service that is available for injection to any part of +the application under the service name "$rootScope". -Different root scopes have different instances of the injector. While typical angular applications -will only have one root scope (and hence the services will act like application singletons), in -tests it is important to not share singletons across test invocations for isolation reasons. We -achieve the necessary isolation by having each test create its own separate root scope. - -<pre> -// create a root scope -var rootScope = angular.module.ng.$rootScope.Scope(); -// access the service locator -var myService = rootScope.$service('myService'); -</pre> ## Inferring dependencies from the signature of the factory function or constructor @@ -74,7 +62,9 @@ equivalent: <pre> // given a user defined service -angular.module.ng('serviceA', ...); +angular.module('module1', [], function($provide) { + $provide.factory('serviceA', ...); +}); // inject '$window', 'serviceA', curry 'name'; function fnA($window, serviceA, name){}; diff --git a/docs/content/guide/dev_guide.scopes.internals.ngdoc b/docs/content/guide/dev_guide.scopes.internals.ngdoc index ca510a21..66d57a9f 100644 --- a/docs/content/guide/dev_guide.scopes.internals.ngdoc +++ b/docs/content/guide/dev_guide.scopes.internals.ngdoc @@ -57,16 +57,18 @@ A property write will always write to the current scope. This means that a write property within the scope it writes to, as shown in the following example. <pre> -var root = angular.module.ng.$rootScope.Scope(); -var child = root.$new(); - -root.name = 'angular'; -expect(child.name).toEqual('angular'); -expect(root.name).toEqual('angular'); - -child.name = 'super-heroic framework'; -expect(child.name).toEqual('super-heroic framework'); -expect(root.name).toEqual('angular'); +it('should inherit properties', inject(function($rootScope)) { + var root = $rootScope; + var child = root.$new(); + + root.name = 'angular'; + expect(child.name).toEqual('angular'); + expect(root.name).toEqual('angular'); + + child.name = 'super-heroic framework'; + expect(child.name).toEqual('super-heroic framework'); + expect(root.name).toEqual('angular'); +}); </pre> @@ -172,8 +174,8 @@ doesn't need to worry about propagating the `$digest` call from the parent scope This happens automatically. ## Scopes in unit-testing -You can create scopes, including the root scope, in tests using the {@link api/angular.module.ng.$rootScope.Scope -angular.module.ng.$rootScope.Scope()} API. This allows you to mimic the run-time environment and have full control over +You can create scopes, including the root scope, in tests by having the $rootScope injected into +your spec. This allows you to mimic the run-time environment and have full control over the life cycle of the scope so that you can assert correct model transitions. Since these scopes are created outside the normal compilation process, their life cycles must be managed by the test. @@ -183,18 +185,20 @@ within the unit-tests. <pre> // example of a test - var scope = angular.module.ng.$rootScope.Scope(); - scope.$watch('name', function(scope, name){ - scope.greeting = 'Hello ' + name + '!'; - }); - - scope.name = 'angular'; - // The watch does not fire yet since we have to manually trigger the digest phase. - expect(scope.greeting).toEqual(undefined); - - // manually trigger digest phase from the test - scope.$digest(); - expect(scope.greeting).toEqual('Hello Angular!'); + it('should trigger a watcher', inject(function($rootScope) { + var scope = $rootScope; + scope.$watch('name', function(scope, name){ + scope.greeting = 'Hello ' + name + '!'; + }); + + scope.name = 'angular'; + // The watch does not fire yet since we have to manually trigger the digest phase. + expect(scope.greeting).toEqual(undefined); + + // manually trigger digest phase from the test + scope.$digest(); + expect(scope.greeting).toEqual('Hello Angular!'); + } </pre> diff --git a/docs/content/guide/dev_guide.services.creating_services.ngdoc b/docs/content/guide/dev_guide.services.creating_services.ngdoc index 06d57d77..4ce16a76 100644 --- a/docs/content/guide/dev_guide.services.creating_services.ngdoc +++ b/docs/content/guide/dev_guide.services.creating_services.ngdoc @@ -1,51 +1,100 @@ @ngdoc overview -@name Developer Guide: Angular Services: Creating Angular Services +@name Developer Guide: Angular Services: Creating Services @description While angular offers several useful services, for any nontrivial application you'll find it useful to write your own custom services. To do this you begin by registering a service factory function -that angular's DI will use to create the service object when it is needed. - -The `angular.module.ng` method accepts three parameters: - -- `{string} name` - Name of the service. -- `{function()} factory` - Factory function(called just once by DI). -- `{Object} config` - Configuration object with the following properties: - - `$inject` - {Array.<string>} - Array of service ids this service depends on. These services -will be passed as arguments into the factory function in the same order specified in the `$inject` -array. Defaults to `[]`. - -The `this` of the factory function is bound to the root scope of the angular application. +with a module either via the {@link api/angular.module Module#factory api} or directly +via the {@link api/angular.module.AUTO.$provide $provide} api inside of module config function. All angular services participate in {@link dev_guide.di dependency injection (DI)} by registering -themselves with angular's DI system (injector) under a `name` (id) as well as by declaring +themselves with Angular's DI system (injector) under a `name` (id) as well as by declaring dependencies which need to be provided for the factory function of the registered service. The ability to swap dependencies for mocks/stubs/dummies in tests allows for services to be highly testable. + +# Registering Services + +To register a service, you must have a module that this service will be part of. Afterwards, you +can register the service with the module either via the {@link api/angular.Module Module api} or +by using the {@link api/angular.module.AUTO.$provide $provide} service in the module configuration +function.The following pseudo-code shows both approaches: + +Using the angular.Module api: +<pre> +var myModule = angular.module('myModule', []); +myModule.factory('serviceId', function() { + var shinyNewServiceInstance; + //factory function body that constructs shinyNewServiceInstance + return shinyNewServiceInstance; +}); +</pre> + +Using the $provide service: +<pre> +angular.module('myModule', [], function($provide) { + $provide.factory('serviceId', function() { + var shinyNewServiceInstance; + //factory function body that constructs shinyNewServiceInstance + return shinyNewServiceInstance; + }); +}); +</pre> + +Note that you are not registering a service instance, but rather a factory function that will +create this instance when called. + + +# Dependencies + +Services can not only be depended upon, but also have its own dependencies. These can be specified +as arguments of the factory function. {@link dev_guide.di.understanding_di Read more} about the DI +in Angular and the use of array notation and $inject property to make DI annotation +minification-proof. + Following is an example of a very simple service. This service depends on the `$window` service (which is passed as a parameter to the factory function) and is just a function. The service simply stores all notifications; after the third one, the service displays all of the notifications by window alert. <pre> - angular.module.ng('notify', function(win) { - var msgs = []; - return function(msg) { - msgs.push(msg); - if (msgs.length == 3) { - win.alert(msgs.join("\n")); - msgs = []; - } - }; - }, {$inject: ['$window']}); +angular.module('myModule', [], function($provide) { + $provide.factory('notify', ['$window', function(win) { + var msgs = []; + return function(msg) { + msgs.push(msg); + if (msgs.length == 3) { + win.alert(msgs.join("\n")); + msgs = []; + } + }; + }]); +}); </pre> +# Instantiating Angular Services + +All services in Angular are instantiates services lazily, this means that a service will be created +only when it is needed for instantiation of a service or an application component that depends on it. +In other words, angular won't instantiate lazy services unless they are requested directly or +indirectly by the application. + + +# Services as singletons + +Lastly, it is important to realize that all angular services are application singletons. This means +that there is only one instance of a given service per injector. Since angular is lethally allergic +to the global state, it is possible to create multiple injectors, each with its own instance of a +given service, but that is rarely needed, except in tests where this property is crucially +important. + + + ## Related Topics * {@link dev_guide.services.understanding_services Understanding Angular Services} -* {@link dev_guide.services.registering_services Registering Angular Services} * {@link dev_guide.services.managing_dependencies Managing Service Dependencies} * {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers } * {@link dev_guide.services.testing_services Testing Angular Services} diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc index e98eb5e0..9f48d3c7 100644 --- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc +++ b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc @@ -71,7 +71,6 @@ it('should test service', function() { {@link dev_guide.services.understanding_services Understanding Angular Services} {@link dev_guide.services.creating_services Creating Angular Services} -{@link dev_guide.services.registering_services Registering Angular Services} {@link dev_guide.services.managing_dependencies Managing Service Dependencies} {@link dev_guide.services.testing_services Testing Angular Services} diff --git a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc index 43e5a4ae..bccc6539 100644 --- a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc +++ b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc @@ -5,12 +5,42 @@ Angular allows services to declare other services as dependencies needed for construction of their instances. -To declare dependencies, you specify them in the factory function signature and via the `$inject` -property, as an array of string identifiers. Optionally the `$inject` property declaration can be +To declare dependencies, you specify them in the factory function signature and annotate the +function with the inject annotations either using by setting the `$inject` property, as an array of +string identifiers or using the array notation. Optionally the `$inject` property declaration can be dropped (see "Inferring `$inject`" but note that that is currently an experimental feature). +Using the array notation: + +<pre> +function myModuleCfgFn($provide) { + $provide.factory('myService', ['dep1', 'dep2', function(dep1, dep2) {}]); +} +</pre> + + +Using the $inject property: + +<pre> +function myModuleCfgFn($provide) { + var myServiceFactory = function(dep1, dep2) {}; + myServiceFactory.$inject = ['dep1', 'dep2']; + $provide.factory('myService', myServiceFactory); +} +</pre> + + +Using DI inference (incompatible with minifiers): + +<pre> +function myModuleCfgFn($provide) { + $provide.factory('myService', function(dep1, dep2) {}); +} +</pre> + + Here is an example of two services that depend on each other, as well as on other services that are -provided by angular's web framework: +provided by Angular's web framework: <pre> /** @@ -63,22 +93,21 @@ Things to notice in this example: `console.log` in batches. * The `routeTemplateMonitor` service depends on the built-in {@link api/angular.module.ng.$route $route} service as well as our custom `batchLog` service. -* Both of our services use the factory function signature as well as the `$inject` property to -declare their dependencies. It is important that the order of the string identifiers in the array -associated with the `$inject` property is the same as the order of argument names in the signature -of the factory function. Unless the dependencies are inferred from the function signature, it is -this array with IDs and their order that the injector uses to determine which services and in which -order to inject. +* Both of our services use the factory function signature and array notation for inject annotations +to declare their dependencies. It is important that the order of the string identifiers in the array +is the same as the order of argument names in the signature of the factory function. Unless the +dependencies are inferred from the function signature, it is this array with IDs and their order +that the injector uses to determine which services and in which order to inject. ## Related Topics * {@link dev_guide.services.understanding_services Understanding Angular Services} * {@link dev_guide.services.creating_services Creating Angular Services} -* {@link dev_guide.services.registering_services Registering Services} * {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers } * {@link dev_guide.services.testing_services Testing Angular Services} + ## Related API * {@link api/angular.module.ng Angular Service API} diff --git a/docs/content/guide/dev_guide.services.ngdoc b/docs/content/guide/dev_guide.services.ngdoc index d59dafe9..bd000507 100644 --- a/docs/content/guide/dev_guide.services.ngdoc +++ b/docs/content/guide/dev_guide.services.ngdoc @@ -12,9 +12,8 @@ most often used with {@link dev_guide.di dependency injection}, also a key featu * {@link dev_guide.services.understanding_services Understanding Angular Services} * {@link dev_guide.services.creating_services Creating Angular Services} -* {@link dev_guide.services.registering_services Registering Angular Services} * {@link dev_guide.services.managing_dependencies Managing Service Dependencies} -* {@link dev_guide.services.injecting_controllers Injecting Services Into Conrollers} +* {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers} * {@link dev_guide.services.testing_services Testing Angular Services} ## Related API diff --git a/docs/content/guide/dev_guide.services.registering_services.ngdoc b/docs/content/guide/dev_guide.services.registering_services.ngdoc deleted file mode 100644 index 25a51504..00000000 --- a/docs/content/guide/dev_guide.services.registering_services.ngdoc +++ /dev/null @@ -1,64 +0,0 @@ -@ngdoc overview -@name Developer Guide: Angular Services: Registering Angular Services -@description - -To register a service, retrieve the {@link api/angular.module.AUTO.$provide $provide} service and use one of itse -registration methods for new service declaration. The following pseudo-code shows a simple service registration: - -<pre> -$provide.factory('service id', function() { - var shinyNewServiceInstance; - //factory function body that constructs shinyNewServiceInstance - return shinyNewServiceInstance; -}); -</pre> - -Note that you are not registering a service instance, but rather a factory function that will -create this instance when called. - -# Instantiating Angular Services - -A service can be instantiated eagerly or lazily. By default angular instantiates services lazily, -which means that a service will be created only when it is needed for instantiation of a service or -an application component that depends on it. In other words, angular won't instantiate lazy -services unless they are requested directly or indirectly by the application. - -Eager services on the other hand, are instantiated right after the injector itself is created, -which happens when the angular {@link dev_guide.bootstrap application initializes}. - -To override the default, you can request that a service is eagerly instantiated as follows: - -<pre> -angular.module.ng('service id', function() { - var shinyNewServiceInstance; - //factory function body that constructs shinyNewServiceInstance - return shinyNewServiceInstance; -}); -</pre> - -* Nothing in your application declares this service as its dependency, and this service affects the -state or configuration of the application (e.g. a service that configures `$route` or `$resource` -services) -* A guarantee is needed that the service will be instantiated at application boot time, usually -because the service passively observes the application and it is optional for other application -components to depend on it. An example of this scenario is a service that monitors and logs -application memory usage. - -Lastly, it is important to realize that all angular services are applicaiton singletons. This means -that there is only one instance of a given service per injector. Since angular is lethally allergic -to the global state, it is possible to create multiple injectors, each with its own instance of a -given service, but that is rarely needed, except in tests where this property is crucially -important. - - -## Related Topics - -* {@link dev_guide.services.understanding_services Understanding Angular Services} -* {@link dev_guide.services.creating_services Creating Angular Services} -* {@link dev_guide.services.managing_dependencies Managing Service Dependencies} -* {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers } -* {@link dev_guide.services.testing_services Testing Angular Services} - -## Related API - -* {@link api/angular.module.ng Angular Service API} diff --git a/docs/content/guide/dev_guide.services.testing_services.ngdoc b/docs/content/guide/dev_guide.services.testing_services.ngdoc index c18cfda1..d867215b 100644 --- a/docs/content/guide/dev_guide.services.testing_services.ngdoc +++ b/docs/content/guide/dev_guide.services.testing_services.ngdoc @@ -11,7 +11,14 @@ var mock, notify; beforeEach(function() { mock = {alert: jasmine.createSpy()}; - notify = angular.module.ng('notify')(mock); + + module(function($provide) { + $provide.value('$window', mock); + }); + + inject(function($injector) { + notify = $injector.get('notify'); + }); }); it('should not alert first two notifications', function() { @@ -47,12 +54,9 @@ it('should clear messages after alert', function() { * {@link dev_guide.services.understanding_services Understanding Angular Services} * {@link dev_guide.services.creating_services Creating Angular Services} -* {@link dev_guide.services.registering_services Registering Angular Services} * {@link dev_guide.services.managing_dependencies Managing Service Dependencies} * {@link dev_guide.services.injecting_controllers Injecting Services Into Conrollers} ## Related API * {@link api/angular.module.ng Angular Service API} - - diff --git a/docs/content/guide/dev_guide.services.understanding_services.ngdoc b/docs/content/guide/dev_guide.services.understanding_services.ngdoc index ac4a7909..390ced0c 100644 --- a/docs/content/guide/dev_guide.services.understanding_services.ngdoc +++ b/docs/content/guide/dev_guide.services.understanding_services.ngdoc @@ -12,14 +12,14 @@ of the rest. The angular injector subsystem is in charge of service instantiatio dependencies, and provision of dependencies to factory functions as requested. Angular injects dependencies using "constructor" injection (the service is passed in via a factory -function). Because JavaScript is a dynamically typed language, angular's dependency injection +function). Because JavaScript is a dynamically typed language, Angular's dependency injection subsystem cannot use static types to identify service dependencies. For this reason a dependent must explicitly define its dependencies by using the `$inject` property. For example: myController.$inject = ['$location']; The angular web framework provides a set of services for common operations. Like other core angular -variables and identifiers, the built-in services always start with `$` (such as `$xhr` mentioned +variables and identifiers, the built-in services always start with `$` (such as `$http` mentioned above). You can also create your own custom services. @@ -27,7 +27,6 @@ above). You can also create your own custom services. * {@link dev_guide.di About Angular Dependency Injection} * {@link dev_guide.services.creating_services Creating Angular Services} -* {@link dev_guide.services.registering_services Registering Angular Services} * {@link dev_guide.services.managing_dependencies Managing Service Dependencies} * {@link dev_guide.services.testing_services Testing Angular Services} diff --git a/docs/content/guide/dev_guide.templates.filters.ngdoc b/docs/content/guide/dev_guide.templates.filters.ngdoc index 52780ec0..0308edb2 100644 --- a/docs/content/guide/dev_guide.templates.filters.ngdoc +++ b/docs/content/guide/dev_guide.templates.filters.ngdoc @@ -11,7 +11,8 @@ displaying it to the user. You can pass expressions through a chain of filters l name | uppercase -The expression evaluator simply passes the value of name to `angular.module.ng.$filter.uppercase()`. +The expression evaluator simply passes the value of name to +{@link api/angular.module.ng.$filter.uppercase uppercase filter}. In addition to formatting data, filters can also modify the DOM. This allows filters to handle tasks such as conditionally applying CSS styles to filtered output. diff --git a/docs/content/guide/dev_guide.unit-testing.ngdoc b/docs/content/guide/dev_guide.unit-testing.ngdoc index 8b4d4687..a14ddd39 100644 --- a/docs/content/guide/dev_guide.unit-testing.ngdoc +++ b/docs/content/guide/dev_guide.unit-testing.ngdoc @@ -252,11 +252,13 @@ format. They are important because they remove the formatting responsibility fro logic, further simplifying the application logic. <pre> -angular.module.ng.$filter('length', function(text){ - return (''+(text||'')).length; +myModule.filter('length', function() { + return function(text){ + return (''+(text||'')).length; + } }); -var length = angular.module.ng.$filter('length'); +var length = $filter('length'); expect(length(null)).toEqual(0); expect(length('abc')).toEqual(3); </pre> diff --git a/docs/content/guide/index.ngdoc b/docs/content/guide/index.ngdoc index ff66f770..8066d095 100644 --- a/docs/content/guide/index.ngdoc +++ b/docs/content/guide/index.ngdoc @@ -47,7 +47,6 @@ of the following documents before returning here to the Developer Guide: * {@link dev_guide.services.understanding_services Understanding Angular Services} * {@link dev_guide.services.creating_services Creating Angular Services} -* {@link dev_guide.services.registering_services Registering Angular Services} * {@link dev_guide.services.managing_dependencies Managing Service Dependencies} * {@link dev_guide.services.testing_services Testing Angular Services} |
