aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/content/api/angular.filter.ngdoc87
-rw-r--r--docs/content/api/angular.formatter.ngdoc82
-rw-r--r--docs/content/api/angular.service.ngdoc195
-rw-r--r--docs/content/api/angular.validator.ngdoc77
-rw-r--r--docs/content/api/angular.widget.ngdoc78
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>
-&lt;my:watch exp="name"/&gt;
-</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>
-&lt;div my:watch="name"&gt;text&lt;/div&gt;
-</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>