diff options
| author | Igor Minar | 2011-06-06 14:44:49 -0700 |
|---|---|---|
| committer | Igor Minar | 2011-06-06 23:10:28 -0700 |
| commit | 3069566073ef07700dc29714f74dd6f2069caf90 (patch) | |
| tree | d406f77758faf780c32bf14b5bc2be7c960a7664 /docs/content/api | |
| parent | bd9a7b9fd71147113a08d8e5736024a8cd6f1979 (diff) | |
| download | angular.js-3069566073ef07700dc29714f74dd6f2069caf90.tar.bz2 | |
api doc fixes from ken
Diffstat (limited to 'docs/content/api')
| -rw-r--r-- | docs/content/api/angular.filter.ngdoc | 87 | ||||
| -rw-r--r-- | docs/content/api/angular.formatter.ngdoc | 82 | ||||
| -rw-r--r-- | docs/content/api/angular.service.ngdoc | 195 | ||||
| -rw-r--r-- | docs/content/api/angular.validator.ngdoc | 77 | ||||
| -rw-r--r-- | docs/content/api/angular.widget.ngdoc | 78 |
5 files changed, 169 insertions, 350 deletions
diff --git a/docs/content/api/angular.filter.ngdoc b/docs/content/api/angular.filter.ngdoc deleted file mode 100644 index 5d4f5940..00000000 --- a/docs/content/api/angular.filter.ngdoc +++ /dev/null @@ -1,87 +0,0 @@ -@workInProgress -@ngdoc overview -@name angular.filter -@namespace Namespace for all filters. -@description -# Overview -Filters are a standard way to format your data for display to the user. For example, you -might have the number 1234.5678 and would like to display it as US currency: $1,234.57. -Filters allow you to do just that. In addition to transforming the data, filters also modify -the DOM. This allows the filters to for example apply css styles to the filtered output if -certain conditions were met. - - -# Standard Filters - -The Angular framework provides a standard set of filters for common operations, including: -{@link angular.filter.currency currency}, {@link angular.filter.json json}, -{@link angular.filter.number number}, and {@link angular.filter.html html}. You can also add -your own filters. - - -# Syntax - -Filters can be part of any {@link angular.scope} evaluation but are typically used with -{{bindings}}. Filters typically transform the data to a new data type, formating the data in -the process. Filters can be chained and take optional arguments. Here are few examples: - -* No filter: {{1234.5678}} => 1234.5678 -* Number filter: {{1234.5678|number}} => 1,234.57. Notice the “,” and rounding to two - significant digits. -* Filter with arguments: {{1234.5678|number:5}} => 1,234.56780. Filters can take optional - arguments, separated by colons in a binding. To number, the argument “5” requests 5 digits - to the right of the decimal point. - - -# Writing your own Filters - -Writing your own filter is very easy: just define a JavaScript function on `angular.filter`. -The framework passes in the input value as the first argument to your function. Any filter -arguments are passed in as additional function arguments. - -You can use these variables in the function: - -* `this` — The current scope. -* `this.$element` — The DOM element containing the binding. This allows the filter to manipulate - the DOM in addition to transforming the input. - - -@example - The following example filter reverses a text string. In addition, it conditionally makes the - text upper-case (to demonstrate optional arguments) and assigns color (to demonstrate DOM - modification). - -<doc:example> - <doc:source> - <script type="text/javascript"> - angular.filter('reverse', function(input, uppercase, color) { - var out = ""; - for (var i = 0; i < input.length; i++) { - out = input.charAt(i) + out; - } - if (uppercase) { - out = out.toUpperCase(); - } - if (color) { - this.$element.css('color', color); - } - return out; - }); - </script> - - <input name="text" type="text" value="hello" /><br> - No filter: {{text}}<br> - Reverse: {{text|reverse}}<br> - Reverse + uppercase: {{text|reverse:true}}<br> - Reverse + uppercase + blue: {{text|reverse:true:"blue"}} - </doc:source> - <doc:scenario> - it('should reverse text', function(){ - expect(binding('text|reverse')).toEqual('olleh'); - input('text').enter('ABC'); - expect(binding('text|reverse')).toEqual('CBA'); - }); - </doc:scenario> -</doc:example> - - diff --git a/docs/content/api/angular.formatter.ngdoc b/docs/content/api/angular.formatter.ngdoc deleted file mode 100644 index 4eef190e..00000000 --- a/docs/content/api/angular.formatter.ngdoc +++ /dev/null @@ -1,82 +0,0 @@ -@workInProgress -@ngdoc overview -@name angular.formatter -@namespace Namespace for all formats. -@description -# Overview -The formatters are responsible for translating user readable text in an input widget to a -data model stored in an application. - -# Writting your own Formatter -Writing your own formatter is easy. Just register a pair of JavaScript functions with -`angular.formatter`. One function for parsing user input text to the stored form, -and one for formatting the stored data to user-visible text. - -Here is an example of a "reverse" formatter: The data is stored in uppercase and in -reverse, while it is displayed in lower case and non-reversed. User edits are -automatically parsed into the internal form and data changes are automatically -formatted to the viewed form. - -<pre> -function reverse(text) { - var reversed = []; - for (var i = 0; i < text.length; i++) { - reversed.unshift(text.charAt(i)); - } - return reversed.join(''); -} - -angular.formatter('reverse', { - parse: function(value){ - return reverse(value||'').toUpperCase(); - }, - format: function(value){ - return reverse(value||'').toLowerCase(); - } -}); -</pre> - -@example -<doc:example> - <doc:source> - <script type="text/javascript"> - function reverse(text) { - var reversed = []; - for (var i = 0; i < text.length; i++) { - reversed.unshift(text.charAt(i)); - } - return reversed.join(''); - } - - angular.formatter('reverse', { - parse: function(value){ - return reverse(value||'').toUpperCase(); - }, - format: function(value){ - return reverse(value||'').toLowerCase(); - } - }); - </script> - - Formatted: - <input type="text" name="data" value="angular" ng:format="reverse"/> - <br/> - - Stored: - <input type="text" name="data"/><br/> - <pre>{{data}}</pre> - </doc:source> - <doc:scenario> - it('should store reverse', function(){ - expect(element('.doc-example-live input:first').val()).toEqual('angular'); - expect(element('.doc-example-live input:last').val()).toEqual('RALUGNA'); - - this.addFutureAction('change to XYZ', function($window, $document, done){ - $document.elements('.doc-example-live input:last').val('XYZ').trigger('change'); - done(); - }); - expect(element('.doc-example-live input:first').val()).toEqual('zyx'); - }); - </doc:scenario> -</doc:example> - diff --git a/docs/content/api/angular.service.ngdoc b/docs/content/api/angular.service.ngdoc index 9a191921..0d3406e5 100644 --- a/docs/content/api/angular.service.ngdoc +++ b/docs/content/api/angular.service.ngdoc @@ -1,32 +1,175 @@ @workInProgress @ngdoc overview @name angular.service + @description +# Overview +Services are substituable objects, which are wired together using dependency injection (DI). +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 identify these dependencies, so each service must explicitely define its dependencies. +This is done by `$inject` property. + + +# Built-in services +angular provides a set of services for common operations. These services can be overriden by custom +services if needed. + +Like other core angular variables and identifiers, the built-in services always start with `$`. + + * {@link angular.service.$browser $browser} + * {@link angular.service.$window $window} + * {@link angular.service.$document $document} + * {@link angular.service.$location $location} + * {@link angular.service.$log $log} + * {@link angular.service.$exceptionHandler $exceptionHandler} + * {@link angular.service.$hover $hover} + * {@link angular.service.$invalidWidgets $invalidWidgets} + * {@link angular.service.$route $route} + * {@link angular.service.$xhr $xhr} + * {@link angular.service.$xhr.error $xhr.error} + * {@link angular.service.$xhr.bulk $xhr.bulk} + * {@link angular.service.$xhr.cache $xhr.cache} + * {@link angular.service.$resource $resource} + * {@link angular.service.$cookies $cookies} + * {@link angular.service.$cookieStore $cookieStore} + +# Writing your own custom services +angular provides only set of basic services, so for any nontrivial application it will be necessary +to write one or more custom services. To do so, a factory function that creates a services needs to +be registered with angular's dependency injector. This factory function must return an object - the +service (it is not called with the `new` operator). + +**angular.service** accepts three parameters: + + - `{string} name` - Name of the service. + - `{function()} factory` - Factory function (called just once by DI). + - `{Object} config` - Configuration object with following properties: + - `$inject` - {Array.<string>} - Array of service ids that this service depends on. These + services will be passed as arguments into the factory function in the same order as specified + in the `$inject` array. Defaults to `[]`. + - `$eager` - {boolean} - If true, the service factory will be called and thus, the service will + be instantiated when angular boots. If false, service will be lazily instantiated when it is + first requested during instantiation of a dependant. Defaults to `false`. + +The `this` of the factory function is bound to the root scope of the angular application. + +angular enables services to participate in dependency injection (DI) by registering 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. + +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(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 as dependencies for controllers is very similar to using them as dependencies for +another service. + +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 +<doc:example> + <doc:source> + <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> -The services API provides objects for carrying out common web app tasks. Service objects are -managed by angular's {@link guide/dev_guide.di dependency injection system}. - - -* {@link angular.service.$browser $browser } - Provides an instance of a browser object -* {@link angular.service.$cookieStore $cookieStore } - Provides key / value storage backed by -session cookies -* {@link angular.service.$cookies $cookies } - Provides read / write access to browser cookies -* {@link angular.service.$defer $defer } - Defers function execution and try / catch block -* {@link angular.service.$document $document } - Provides reference to `window.document` element -* {@link angular.service.$exceptionHandler $exceptionHandler } - Receives uncaught angular -exceptions -* {@link angular.service.$hover $hover } - -* {@link angular.service.$invalidWidgets $invalidWidgets } - Holds references to invalid widgets -* {@link angular.service.$location $location } - Parses the browser location URL -* {@link angular.service.$log $log } - Provides logging service -* {@link angular.service.$resource $resource } - Creates objects for interacting with RESTful -server-side data sources -* {@link angular.service.$route $route } - Provides deep-linking services -* {@link angular.service.$updateView $updateView } - Queues view updates -* {@link angular.service.$window $window } - References the browsers `window` object -* {@link angular.service.$xhr $xhr} - Generates an XHR request. - - -For information on how angular services work and how to write your own services, see {@link -guide/dev_guide.services Angular Services} in the angular Developer Guide. + <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> + </doc:source> + <doc:scenario> + it('should test service', function(){ + expect(element(':input[name=message]').val()).toEqual('test'); + }); + </doc:scenario> +</doc:example> diff --git a/docs/content/api/angular.validator.ngdoc b/docs/content/api/angular.validator.ngdoc deleted file mode 100644 index 96b1e76a..00000000 --- a/docs/content/api/angular.validator.ngdoc +++ /dev/null @@ -1,77 +0,0 @@ -@workInProgress -@ngdoc overview -@name angular.validator -@namespace Namespace for all filters. -@description -# Overview -Validators are a standard way to check the user input against a specific criteria. For -example, you might need to check that an input field contains a well-formed phone number. - -# Syntax -Attach a validator on user input widgets using the `ng:validate` attribute. - -<doc:example> - <doc:source> - Change me: <input type="text" name="number" ng:validate="integer" value="123"> - </doc:source> - <doc:scenario> - it('should validate the default number string', function() { - expect(element('input[name=number]').attr('class')). - not().toMatch(/ng-validation-error/); - }); - it('should not validate "foo"', function() { - input('number').enter('foo'); - expect(element('input[name=number]').attr('class')). - toMatch(/ng-validation-error/); - }); - </doc:scenario> -</doc:example> - - -# Writing your own Validators -Writing your own validator is easy. To make a function available as a -validator, just define the JavaScript function on the `angular.validator` -object. <angular/> passes in the input to validate as the first argument -to your function. Any additional validator arguments are passed in as -additional arguments to your function. - -You can use these variables in the function: - -* `this` — The current scope. -* `this.$element` — The DOM element containing the binding. This allows the filter to manipulate - the DOM in addition to transforming the input. - -In this example we have written a upsTrackingNo validator. -It marks the input text "valid" only when the user enters a well-formed -UPS tracking number. - -@css ng-validation-error - When validation fails, this css class is applied to the binding, making its borders red by - default. - -@example -<doc:example> - <doc:source> - <script> - angular.validator('upsTrackingNo', function(input, format) { - var regexp = new RegExp("^" + format.replace(/9/g, '\\d') + "$"); - return input.match(regexp)?"":"The format must match " + format; - }); - </script> - <input type="text" name="trackNo" size="40" - ng:validate="upsTrackingNo:'1Z 999 999 99 9999 999 9'" - value="1Z 123 456 78 9012 345 6"/> - </doc:source> - <doc:scenario> - it('should validate correct UPS tracking number', function() { - expect(element('input[name=trackNo]').attr('class')). - not().toMatch(/ng-validation-error/); - }); - - it('should not validate in correct UPS tracking number', function() { - input('trackNo').enter('foo'); - expect(element('input[name=trackNo]').attr('class')). - toMatch(/ng-validation-error/); - }); - </doc:scenario> -</doc:example> diff --git a/docs/content/api/angular.widget.ngdoc b/docs/content/api/angular.widget.ngdoc deleted file mode 100644 index 5fd7b259..00000000 --- a/docs/content/api/angular.widget.ngdoc +++ /dev/null @@ -1,78 +0,0 @@ -@workInProgress -@ngdoc overview -@name angular.widget -@namespace Namespace for all widgets. -@description -# Overview -Widgets allow you to create DOM elements that the browser doesn't -already understand. You create the widget in your namespace and -assign it behavior. You can only bind one widget per DOM element -(unlike directives, in which you can use any number per DOM -element). Widgets are expected to manipulate the DOM tree by -adding new elements whereas directives are expected to only modify -element properties. - -Widgets come in two flavors: element and attribute. - -# Element Widget -Let's say we would like to create a new element type in the -namespace `my` that can watch an expression and alert() the user -with each new value. - -<pre> -<my:watch exp="name"/> -</pre> - -You can implement `my:watch` like this: -<pre> -angular.widget('my:watch', function(compileElement) { - var compiler = this; - var exp = compileElement.attr('exp'); - return function(linkElement) { - var currentScope = this; - currentScope.$watch(exp, function(value){ - alert(value); - }); - }; -}); -</pre> - -# Attribute Widget -Let's implement the same widget, but this time as an attribute -that can be added to any existing DOM element. -<pre> -<div my:watch="name">text</div> -</pre> -You can implement `my:watch` attribute like this: -<pre> -angular.widget('@my:watch', function(expression, compileElement) { - var compiler = this; - return function(linkElement) { - var currentScope = this; - currentScope.$watch(expression, function(value){ - alert(value); - }); - }; -}); -</pre> - -@example -<doc:example> - <doc:source> - <script> - angular.widget('my:time', function(compileElement){ - compileElement.css('display', 'block'); - return function(linkElement){ - function update(){ - linkElement.text('Current time is: ' + new Date()); - setTimeout(update, 1000); - } - update(); - }; - }); - </script> - <my:time></my:time> - </doc:source> - <doc:scenario> - </doc:scenario> -</doc:example> |
