From 7f1e2e48467f80cc083d24b44f088620e4e7bcb6 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Mon, 6 Jun 2011 08:50:35 -0700 Subject: new batch of docs --- .../guide/dev_guide.bootstrap.auto_bootstrap.ngdoc | 130 +++++++++ .../dev_guide.bootstrap.manual_bootstrap.ngdoc | 58 ++++ docs/content/guide/dev_guide.bootstrap.ngdoc | 86 ++++++ ...e.compiler.directives.creating_directives.ngdoc | 49 ++++ .../guide/dev_guide.compiler.directives.ngdoc | 61 ++++ .../dev_guide.compiler.directives_widgets.ngdoc | 59 ++++ .../dev_guide.compiler.extending_compiler.ngdoc | 115 ++++++++ docs/content/guide/dev_guide.compiler.markup.ngdoc | 120 ++++++++ docs/content/guide/dev_guide.compiler.ngdoc | 35 +++ .../dev_guide.compiler.testing_dom_element.ngdoc | 25 ++ ...dev_guide.compiler.understanding_compiler.ngdoc | 88 ++++++ ...v_guide.compiler.widgets.creating_widgets.ngdoc | 116 ++++++++ .../content/guide/dev_guide.compiler.widgets.ngdoc | 47 +++ docs/content/guide/dev_guide.di.ngdoc | 43 +++ .../guide/dev_guide.di.understanding_di.ngdoc | 141 +++++++++ .../guide/dev_guide.di.using_di_controllers.ngdoc | 66 +++++ docs/content/guide/dev_guide.expressions.ngdoc | 270 +++++++++++++++++ docs/content/guide/dev_guide.introduction.ngdoc | 53 ++++ docs/content/guide/dev_guide.mvc.ngdoc | 33 +++ .../dev_guide.mvc.understanding_controller.ngdoc | 323 +++++++++++++++++++++ .../guide/dev_guide.mvc.understanding_model.ngdoc | 96 ++++++ .../guide/dev_guide.mvc.understanding_view.ngdoc | 29 ++ docs/content/guide/dev_guide.overview.ngdoc | 288 ++++++++++++++++++ .../dev_guide.scopes.controlling_scopes.ngdoc | 50 ++++ docs/content/guide/dev_guide.scopes.ngdoc | 51 ++++ .../dev_guide.scopes.understanding_scopes.ngdoc | 83 ++++++ .../guide/dev_guide.scopes.updating_scopes.ngdoc | 47 +++ .../guide/dev_guide.scopes.working_scopes.ngdoc | 65 +++++ .../dev_guide.services.creating_services.ngdoc | 71 +++++ .../dev_guide.services.injecting_controllers.ngdoc | 91 ++++++ .../dev_guide.services.managing_dependencies.ngdoc | 96 ++++++ docs/content/guide/dev_guide.services.ngdoc | 29 ++ .../dev_guide.services.registering_services.ngdoc | 86 ++++++ .../dev_guide.services.testing_services.ngdoc | 70 +++++ ...dev_guide.services.understanding_services.ngdoc | 48 +++ docs/content/guide/dev_guide.templates.css.ngdoc | 70 +++++ .../guide/dev_guide.templates.databinding.ngdoc | 48 +++ ..._guide.templates.filters.creating_filters.ngdoc | 74 +++++ .../guide/dev_guide.templates.filters.ngdoc | 38 +++ ...dev_guide.templates.filters.using_filters.ngdoc | 55 ++++ ....templates.formatters.creating_formatters.ngdoc | 63 ++++ .../guide/dev_guide.templates.formatters.ngdoc | 26 ++ ...ide.templates.formatters.using_formatters.ngdoc | 12 + docs/content/guide/dev_guide.templates.ngdoc | 75 +++++ ....templates.validators.creating_validators.ngdoc | 100 +++++++ .../guide/dev_guide.templates.validators.ngdoc | 160 ++++++++++ docs/content/guide/dev_guide.unit-testing.ngdoc | 323 +++++++++++++++++++++ docs/content/guide/index.ngdoc | 104 +++++-- 48 files changed, 4237 insertions(+), 29 deletions(-) create mode 100644 docs/content/guide/dev_guide.bootstrap.auto_bootstrap.ngdoc create mode 100644 docs/content/guide/dev_guide.bootstrap.manual_bootstrap.ngdoc create mode 100644 docs/content/guide/dev_guide.bootstrap.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.directives.creating_directives.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.directives.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.directives_widgets.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.extending_compiler.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.markup.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.testing_dom_element.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.understanding_compiler.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.widgets.creating_widgets.ngdoc create mode 100644 docs/content/guide/dev_guide.compiler.widgets.ngdoc create mode 100644 docs/content/guide/dev_guide.di.ngdoc create mode 100644 docs/content/guide/dev_guide.di.understanding_di.ngdoc create mode 100644 docs/content/guide/dev_guide.di.using_di_controllers.ngdoc create mode 100644 docs/content/guide/dev_guide.expressions.ngdoc create mode 100644 docs/content/guide/dev_guide.introduction.ngdoc create mode 100644 docs/content/guide/dev_guide.mvc.ngdoc create mode 100644 docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc create mode 100644 docs/content/guide/dev_guide.mvc.understanding_model.ngdoc create mode 100644 docs/content/guide/dev_guide.mvc.understanding_view.ngdoc create mode 100644 docs/content/guide/dev_guide.overview.ngdoc create mode 100644 docs/content/guide/dev_guide.scopes.controlling_scopes.ngdoc create mode 100644 docs/content/guide/dev_guide.scopes.ngdoc create mode 100644 docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc create mode 100644 docs/content/guide/dev_guide.scopes.updating_scopes.ngdoc create mode 100644 docs/content/guide/dev_guide.scopes.working_scopes.ngdoc create mode 100644 docs/content/guide/dev_guide.services.creating_services.ngdoc create mode 100644 docs/content/guide/dev_guide.services.injecting_controllers.ngdoc create mode 100644 docs/content/guide/dev_guide.services.managing_dependencies.ngdoc create mode 100644 docs/content/guide/dev_guide.services.ngdoc create mode 100644 docs/content/guide/dev_guide.services.registering_services.ngdoc create mode 100644 docs/content/guide/dev_guide.services.testing_services.ngdoc create mode 100644 docs/content/guide/dev_guide.services.understanding_services.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.css.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.databinding.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.filters.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.filters.using_filters.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.formatters.creating_formatters.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.formatters.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.formatters.using_formatters.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.validators.creating_validators.ngdoc create mode 100644 docs/content/guide/dev_guide.templates.validators.ngdoc create mode 100644 docs/content/guide/dev_guide.unit-testing.ngdoc (limited to 'docs/content/guide') diff --git a/docs/content/guide/dev_guide.bootstrap.auto_bootstrap.ngdoc b/docs/content/guide/dev_guide.bootstrap.auto_bootstrap.ngdoc new file mode 100644 index 00000000..1c5e3e26 --- /dev/null +++ b/docs/content/guide/dev_guide.bootstrap.auto_bootstrap.ngdoc @@ -0,0 +1,130 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Initializing Angular: Automatic Initiialization +@description + + +Angular initializes automatically when you load the angular script into your page, specifying +angular's `ng:autobind` attribute with no arguments: + + + + + +
+ Hello {{'world'}}! +
+ + + + + +As with `ng:autobind`, you can specify an element id that should be exclusively targeted for +compilation as the value of the `#autobind`, for example: `#autobind=angularContent`. + + +## Filename Restrictions for Auto-bootstrap + + +In order for us to find the auto-bootstrap from a script attribute or URL fragment, the value of +the `script` `src` attribute that loads the angular script must match one of these naming +conventions: + + +- `angular.js` +- `angular-min.js` +- `angular-x.x.x.js` +- `angular-x.x.x.min.js` +- `angular-x.x.x-xxxxxxxx.js` (dev snapshot) +- `angular-x.x.x-xxxxxxxx.min.js` (dev snapshot) +- `angular-bootstrap.js` (used for development of angular) + + +Optionally, any of the filename formats above can be prepended with a relative or absolute URL that +ends with `/`. + + +## Global Angular Object + + +The angular script creates a single global variable `angular` in the global namespace. All angular +APIs are bound to fields of this global object. + + + + +## Related Topics + + +* {@link dev_guide.bootstrap Initializing Angular} +* {@link dev_guide.bootstrap.manual_bootstrap Manual Initialization} + + +## Related API + + +{@link api/angular.compile Compiler API} diff --git a/docs/content/guide/dev_guide.bootstrap.manual_bootstrap.ngdoc b/docs/content/guide/dev_guide.bootstrap.manual_bootstrap.ngdoc new file mode 100644 index 00000000..2cce7b31 --- /dev/null +++ b/docs/content/guide/dev_guide.bootstrap.manual_bootstrap.ngdoc @@ -0,0 +1,58 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Initializing Angular: Manual Initialization +@description + + +Letting angular handle the initialization process (bootstrapping) is a handy way to start using +angular, but advanced users who want more control over the initialization process can choose to use +the manual bootstrapping method instead. + + +The best way to get started with manual bootstrapping is to look at the what happens when you use +{@link api/angular.directive.ng:autobind ng:autobind}, by showing each step of the process +explicitly. + + +
+
+
+
+  
+  
+
+
+Hello {{'World'}}!
+
+
+
+ + +This is the sequence that your code should follow if you bootstrap angular on your own: + + +1. After the page is loaded, find the root of the HTML template, which is typically the root of +the document. +2. Run angular's {@link dev_guide.compiler Angular HTML compiler}, which converts a template into +an executable, bi-directionally bound application. + + + + +## Related Topics + + +* {@link dev_guide.bootstrap Initializing Angular} +* {@link dev_guide.bootstrap.auto_bootstrap Automatic Initialization} +* {@link dev_guide.compiler Angular HTML compiler} + + +## Related API + + +{@link api/angular.compile Compiler API} diff --git a/docs/content/guide/dev_guide.bootstrap.ngdoc b/docs/content/guide/dev_guide.bootstrap.ngdoc new file mode 100644 index 00000000..49bb3a77 --- /dev/null +++ b/docs/content/guide/dev_guide.bootstrap.ngdoc @@ -0,0 +1,86 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Initializing Angular +@description + + +Initializing angular consists of loading the `angular.js` script in your page, and specifying how +angular should process and manage the page. To initialize angular you do the following: + + +* Specify the angular namespace in the `` page +* Choose which flavor of angular script to load (debug or production) +* Specify whether or not angular should process and manage the page automatically (`ng:autobind`) + + +The simplest way to initialize angular is to load the angular script and tell angular to compile +and manage the whole page. You do this as follows: + + +
+
+
+  
+    ...
+  
+  
+    ...
+    
+
+
+
+
+
+
+
+
+
+# Additional Compiler Methods for Custom Widgets
+
+
+The angular compiler exposes methods that you may need to use of when writing your own widgets and
+directives.  For example, the `descend()` method lets you control whether the compiler ignores or
+processes child elements of the element it is compiling.  For information on this and other
+compiler methods, see the {@link api/angular.compile Compiler API doc}.
+
+
+
+
+## Related Topics
+
+
+* {@link dev_guide.compiler Angular HTML Compiler}
+* {@link dev_guide.compiler.directives Angular Directives}
+* {@link dev_guide.compiler.widgets Angular Widgets}
+* {@link dev_guide.compiler.directives.creating_directives Creating Custom Directives}
+
+
+## Related API
+
+
+* {@link api/angular.compile Compiler API}
diff --git a/docs/content/guide/dev_guide.compiler.widgets.ngdoc b/docs/content/guide/dev_guide.compiler.widgets.ngdoc
new file mode 100644
index 00000000..dbe082a6
--- /dev/null
+++ b/docs/content/guide/dev_guide.compiler.widgets.ngdoc
@@ -0,0 +1,47 @@
+@workInProgress
+@ngdoc overview
+@name Developer Guide: Angular HTML Compiler: Understanding Angular Widgets
+@description
+
+
+Widgets are DOM elements that the browser doesn't already understand. Angular provides some
+built-in widgets (such as {@link api/angular.widget.@ng:repeat ng:repeat}), and you can create your
+own custom widgets.
+
+
+Widgets are intended to manipulate the DOM tree by adding new elements (unlike {@link
+dev_guide.compiler.directives angular directives}, which are intended to modify only element
+properties).
+
+
+Widgets come in two types:
+
+
+* Element Widget — A custom DOM element.  An example of a custom element is shown in {@link
+dev_guide.compiler.widgets.creating_widgets Creating Custom Widgets}.
+
+
+* Attribute Widget — A custom attribute on an existing DOM element.  An attribute widget is similar
+to an angular directive, with the main difference being that an attribute widget will always be
+processed before any directives that are specified on the same element.  Only one attribute widget
+is allowed per element.  An example of an attribute widget is shown in {@link
+dev_guide.compiler.widgets.creating_widgets Creating Custom Widgets}.
+
+
+
+
+
+
+## Related Topics
+
+
+* {@link dev_guide.compiler Angular HTML Compiler}
+* {@link dev_guide.compiler.directives Angular Directives}
+* {@link dev_guide.compiler.widgets.creating_widgets Creating Custom Widgets}
+* {@link dev_guide.compiler.directives.creating_directives Creating Custom Directives}
+
+
+## Related API
+
+
+* {@link api/angular.compile Compiler API}
diff --git a/docs/content/guide/dev_guide.di.ngdoc b/docs/content/guide/dev_guide.di.ngdoc
new file mode 100644
index 00000000..a2352cc3
--- /dev/null
+++ b/docs/content/guide/dev_guide.di.ngdoc
@@ -0,0 +1,43 @@
+@workInProgress
+@ngdoc overview
+@name Developer Guide: About Dependency Injection (DI)
+@description
+
+
+Dependency Injection (DI) is an object-oriented software design pattern that supports the
+decoupling and dependency management of application components.
+
+
+The idea behind DI is to decouple each component from all of the other components that it depends
+on to do its particular job. The way this is done in DI is by moving the responsibility for
+managing dependencies out of each individual component and into a provider component. The provider
+(or injector) component manages the life cycles and dependencies for all of the other components in
+an application.
+
+
+Angular has a built-in dependency management subsystem that helps to make your applications easier
+to develop, understand, and test.
+
+
+For more information on DI in general, see {@link http://en.wikipedia.org/wiki/Dependency_injection
+Dependency Injection} at Wikipedia, and {@link http://martinfowler.com/articles/injection.html
+Inversion of Control} by Martin Fowler, or read about DI in your favorite software design pattern
+book.
+
+
+
+
+## Related Topics
+
+
+* {@link dev_guide.di.understanding_di Understanding DI in Angular}
+* {@link dev_guide.services Angular Services}
+
+
+
+
+## Related API
+
+
+* {@link api/angular.service Service API}
+* {@link api/angular.injector Angular Injector API}
diff --git a/docs/content/guide/dev_guide.di.understanding_di.ngdoc b/docs/content/guide/dev_guide.di.understanding_di.ngdoc
new file mode 100644
index 00000000..1b131eaf
--- /dev/null
+++ b/docs/content/guide/dev_guide.di.understanding_di.ngdoc
@@ -0,0 +1,141 @@
+@workInProgress
+@ngdoc overview
+@name Developer Guide: DI: Understanding DI in Angular
+@description
+
+
+
+
+While DI is widely used in statically typed languages such as Java or C++, it has not been widely
+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.service
+services}.
+
+
+Services are objects that handle common tasks in web applications. Angular provides several{@link
+api/angular.service built-in services}, and you can create your 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
+angular's {@link api/angular.service service API}, and all components that depend on services
+define those dependencies as a property (`$inject`). With this information, the DI subsystem
+manages the creation of service objects and the provision of those objects to the components that
+need them, at the time they need them. The following illustration steps through the sequence of
+events:
+
+
+
+
+
+In the illustration above, the dependency injection sequence proceeds as follows:
+
+
+1. Service factory functions are registered with angular's service factory repository.
+2. `ng:autobind` triggers angular's bootstrap sequence, during which angular compiles the template,
+creates the root scope, and creates the dependency injector.
+3. The `ng:controller` directive implicitly creates a new child scope, augmented by the application
+of the `PhoneListCtrl` controller function.
+4. The Injector identifies the `$xhr` service as `PhoneListCtrl` controller's only dependency.
+5. The Injector checks if the `$xhr` service has already been instantiated, and if not uses the
+factory function from the service factory repository to construct it.
+6. DI provides the instance of $xhr service to the PhoneListCtrl controller constructor
+
+
+
+
+## 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.
+
+
+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.
+
+
+
+// create a root scope
+var rootScope = angular.scope();
+// access the service locator
+var myService = rootScope.$service('myService');
+
+ + +## Inferring dependencies from the signature of the factory function or constructor + + +**EXPERIMENTAL FEATURE**: This is an experimental feature. See the important note at the end of +this section for drawbacks. + + +We resort to `$inject` and our own annotation because there is no way in JavaScript to get a list +of arguments. Or is there? It turns out that calling `.toString()` on a function returns the +function declaration along with the argument names as shown below: + + +
+function myFn(a,b){}
+expect(myFn.toString()).toEqual('function myFn(a,b){}');
+
+ + +This means that angular can infer the function names after all and use that information to generate +the `$inject` annotation automatically. Therefore the following two function definitions are +equivalent: + + +
+// given a user defined service
+angular.service('serviceA', ...);
+
+
+// inject '$window', 'serviceA', curry 'name';
+function fnA($window, serviceA, name){};
+fnA.$inject = ['$window', 'serviceA'];
+
+
+// inject '$window', 'serviceA', curry 'name';
+function fnB($window, serviceA_, name){};
+// implies: fnB.$inject = ['$window', 'serviceA'];
+
+ + +If angular does not find a `$inject` annotation on the function, then it calls the `.toString()` +method and tries to infer what should be injected using the following rules: + + +* Any argument starting with `$` is an angular service and will be added to the `$inject` property +array +* Any argument ending with `_` will be added to the `$inject` property array (angular strips the +`_`) +* All arguments following an argument which has neither `$` nor `_` , must not have `$` nor `_` +(these are free arguments for {@link http://en.wikipedia.org/wiki/Currying currying}) + + +**IMPORTANT** +Minifiers/obfuscators change the names of function arguments and will therefore break the `$inject` +inference. For this reason, either explicitly declare the `$inject` or do not use +minifiers/obfuscators. In the future, we may provide a pre-processor which will scan the source +code and insert the `$inject` into the source code so that it can be minified/obfuscated. + + + + +## Related Topics + + +* {@link dev_guide.services Angular Services} + + +## Related API + + +* {@link api/angular.service Services API} diff --git a/docs/content/guide/dev_guide.di.using_di_controllers.ngdoc b/docs/content/guide/dev_guide.di.using_di_controllers.ngdoc new file mode 100644 index 00000000..ea1cb965 --- /dev/null +++ b/docs/content/guide/dev_guide.di.using_di_controllers.ngdoc @@ -0,0 +1,66 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: DI: Using DI in Controllers +@description + + +The most common place to use dependency injection in angular applications is in {@link +dev_guide.mvc.understanding_controller controllers}. Here is a simple example: + + +
+function MyController($route){
+ // configure the route service
+ $route.when(...);
+}
+MyController.$inject = ['$route'];
+
+ + +In this example, the `MyController` constructor function takes one argument, the {@link +api/angular.service.$route $route} service. Angular is then responsible for supplying the instance +of `$route` to the controller when the constructor is instantiated. There are two ways to cause +controller instantiation – by configuring routes with the `$route` service, or by referencing the +controller from the HTML template, as follows: + + +
+
+
+
+
+ ...
+
+
+
+ + +When angular is instantiating your controller, it needs to know what services, if any, should be +injected (passed in as arguments) into the controller. Since there is no reflection in JavaScript, +we have to supply this information to angular in the form of an additional property on the +controller constructor function called `$inject`. Think of it as annotations for JavaScript. + + +
+MyController.$inject = ['$route'];
+
+ + +The information in `$inject` is then used by the {@link api/angular.injector injector} to call the +function with the correct arguments. + + + + +## Related Topics + + +* {@link dev_guide.di About Dependency Injection} +* {@link dev_guide.di.understanding_di Understanding Dependency Injection in Angular} +* {@link dev_guide.services Angular Services} + + +## Related API + + +* {@link api/angular.injector Angular Injector API} diff --git a/docs/content/guide/dev_guide.expressions.ngdoc b/docs/content/guide/dev_guide.expressions.ngdoc new file mode 100644 index 00000000..b0a268e6 --- /dev/null +++ b/docs/content/guide/dev_guide.expressions.ngdoc @@ -0,0 +1,270 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Understanding Angular Expressions +@description + + +Expressions are {@link dev_guide.templates.databinding bindings} that you write in HTML and embed +in templates in order to create views in angular. Angular expressions are similar but not +equivalent to JavaScript expressions. + + +For example, these are all valid expressions in angular: + + +* `1+2={{1+2}}` +* `3*10|currency` +* `Hello {{name}}!` +* `Hello {{'World'}}!` + + + + +## Angular Expressions vs. JS Expressions + + +It might be tempting to think of angular view expressions as JavaScript expressions, but that is +not entirely correct. Angular does not use a simple JavaScript eval of the expression text. You can +think of angular expressions as JavaScript expressions with these differences: + + +* **Attribute Evaluation:** evaluation of all attributes are against the current scope, not to the +global window as in JavaScript. +* **Forgiving:** expression evaluation is forgiving to undefined and null, unlike in JavaScript. +* **No Control Flow Statements:** you cannot do the following from an angular expression: +conditionals, loops, or throw. +* **Type Augmentation:** the scope expression evaluator augments built-in types. +* **Filters:** you can add filters to an expression, for example to convert raw data into a +human-readable format. +* **The $:** angular reserves this prefix to differentiate its API names from others. + + +If, on the other hand, you do want to run arbitrary JavaScript code, you should make it a +controller method and call that. If you want to `eval()` an angular expression from JavaScript, use +the `Scope:$eval()` method. + + +## Example + + + 1+2={{1+2}} + + + it('should calculate expression in binding', function(){ + expect(binding('1+2')).toEqual('3'); + }); + + + + +You can try evaluating different expressions here: + + + + +
+ Expression: + + +
    +
  • + [ X ] + {{expr}} => +
  • +
+
+
+ + it('should allow user expression testing', function(){ + element('.expressions :button').click(); + var li = using('.expressions ul').repeater('li'); + expect(li.count()).toBe(1); + expect(li.row(0)).toEqual(["3*10|currency", "$30.00"]); + }); + +
+ + + + +# Attribute Evaluation + + +Evaluation of all attributes takes place against the current scope. Unlike JavaScript, where names +default to global window properties, angular expressions have to use `$window` to refer to the +global object. For example, if you want to call `alert()`, which is defined on `window`, an +expression must use `$window.alert()`. This is done intentionally to prevent accidental access to +the global state (a common source of subtle bugs). + + + + +
+ Name: + +
+
+ + it('should calculate expression in binding', function(){ + var alertText; + this.addFutureAction('set mock', function($window, $document, done) { + $window.mockWindow = { + alert: function(text){ alertText = text; } + }; + done(); + }); + element(':button:contains(Greet)').click(); + expect(this.addFuture('alert text', function(done) { + done(null, alertText); + })).toBe('Hello World'); + }); + +
+ + +## Forgiving + + +Expression evaluation is forgiving to undefined and null. In JavaScript, evaluating `a.b.c` throws +an exception if `a` is not an object. While this makes sense for a general purpose language, the +expression evaluations are primarily used for data binding, which often look like this: + + + {{a.b.c}} + + +It makes more sense to show nothing than to throw an exception if `a` is undefined (perhaps we are +waiting for the server response, and it will become defined soon). If expression evaluation wasn't +forgiving we'd have to write bindings that clutter the code, for example: `{{((a||{}).b||{}).c}}` + + +Similarly, invoking a function `a.b.c()` on undefined or null simply returns undefined. + + +Assignments work the same way in reverse: + + + a.b.c = 10 + + +...creates the intermediary objects even if a is undefined. + + + + +## No Control Flow Statements + + +You cannot write a control flow statement in an expression. The reason behind this is core to the +angular philosophy that application logic should be in controllers, not in the view. If you need a +conditional (including ternary operators), loop, or to throw from a view expression, delegate to a +JavaScript method instead. + + + + +## Type Augmentation + + +Built-in types have methods like `[].push()`, but the richness of these methods is limited. +Consider the example below, which allows you to do a simple search over a canned set of contacts. +The example would be much more complicated if we did not have the `Array:$filter()`. There is no +built-in method on `Array` called {@link api/angular.array.filter $filter} and angular doesn't add +it to `Array.prototype` because that could collide with other JavaScript frameworks. + + +For this reason the scope expression evaluator augments the built-in types to make them act like +they have extra methods. The actual method for `$filter()` is `angular.Array.filter()`. You can +call it from JavaScript. + + +Extensions: You can further extend the expression vocabulary by adding new methods to +`angular.Array` or `angular.String`, etc. + + + + +
+ Search: + + + + + + +
NamePhone
{{friend.name}}{{friend.phone}}
+
+ + it('should filter the list', function(){ + var tr = using('table.example3').repeater('tr.ng-attr-widget'); + expect(tr.count()).toBe(5); + input('searchText').enter('a'); + expect(tr.count()).toBe(2); + + + }); + +
+ + +## Filters + + +When presenting data to the user, you might need to convert the data from its raw format to a +user-friendly format. For example, you might have a data object that needs to be formatted +according to the locale before displaying it to the user. You can pass expressions through a chain +of filters like this: + + + name | uppercase + + +The expression evaluator simply passes the value of name to angular.filter.uppercase. + + +Chain filters using this syntax: + + + value | filter1 | filter2 + + +You can also pass colon-delimited arguments to filters, for example, to display the number 123 with +2 decimal points: + + + 123 | number:2 + + +# The $ + + +You might be wondering, what is the significance of the $ prefix? It is simply a prefix that +angular uses, to differentiate its API names from others. If angular didn't use $, then evaluating +`a.length()` would return undefined because neither a nor angular define such a property. + + +Consider that in a future version of angular we might choose to add a length method, in which case +the behavior of the expression would change. Worse yet, you the developer could create a length +property and then we would have a collision. This problem exists because angular augments existing +objects with additional behavior. By prefixing its additions with $ we are reserving our namespace +so that angular developers and developers who use angular can develop in harmony without collisions. + + + + +## Related Topics + + +* {@link dev_guide.compiler.markup Understanding Angular Markup} +* {@link dev_guide.templates.filters Understanding Angular Filters} + + +## Related API + + +* {@link api/angular.compile Angular Compiler API} diff --git a/docs/content/guide/dev_guide.introduction.ngdoc b/docs/content/guide/dev_guide.introduction.ngdoc new file mode 100644 index 00000000..0a41cc9b --- /dev/null +++ b/docs/content/guide/dev_guide.introduction.ngdoc @@ -0,0 +1,53 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Introduction +@description + + +Angular is pure client-side technology, written entirely in JavaScript. It works with the +long-established technologies of the web (HTML, CSS, and JavaScript) to make the development of web +apps easier and faster than ever before. + + +One important way that angular simplifies web development is by increasing the level of abstraction +between the developer and most low-level web app development tasks. Angular automatically takes +care of many of these tasks, including: + + +* DOM Manipulation +* Setting Up Listeners and Notifiers +* Input Validation + + +Because angular handles much of the work involved in these tasks, developers can concentrate more +on application logic and less on repetitive, error-prone, lower-level coding. + + +At the same time that angular simplifies the development of web apps, it brings relatively +sophisticated techniques to the client-side, including: + + +* Separation of data, application logic, and presentation components +* Data Binding between data and presentation components +* Services (common web app operations, implemented as substitutable objects) +* Dependency Injection (used primarily for wiring together services) +* An extensible HTML compiler (written entirely in JavaScript) +* Ease of Testing + + +These techniques have been for the most part absent from the client-side for far too long. + + +## Single-page / Round-trip Applications + + +You can use angular to develop both single-page and round-trip apps, but angular is designed +primarily for developing single-page apps. Angular supports browser history, forward and back +buttons, and bookmarking in single-page apps. + + +You normally wouldn't want to load angular with every page change, as would be the case with using +angular in a round-trip app. However, it would make sense to do so if you were adding a subset of +angular's features (for example, templates to leverage angular's data-binding feature) to an +existing round-trip app. You might follow this course of action if you were migrating an older app +to a single-page angular app. diff --git a/docs/content/guide/dev_guide.mvc.ngdoc b/docs/content/guide/dev_guide.mvc.ngdoc new file mode 100644 index 00000000..93ad63f5 --- /dev/null +++ b/docs/content/guide/dev_guide.mvc.ngdoc @@ -0,0 +1,33 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: About MVC in Angular +@description + + +While Model-View-Controller (MVC) has acquired different shades of meaning over the years since it +first appeared, angular incorporates the basic principles behind the original {@link +http://en.wikipedia.org/wiki/Model–view–controller MVC} software design pattern into its way of +building client-side web applications. + + +The MVC pattern greatly summarized: + + +* Separate applications into distinct presentation, data, and logic components +* Encourage loose coupling between these components + + +Along with {@link dev_guide.services services} and {@link dev_guide.di dependency injection}, MVC +makes angular applications better structured, easier to maintain and more testable. + + +The following topics explain how angular incorporates the MVC pattern into the angular way of +developing web applications: + + +* {@link dev_guide.mvc.understanding_model Understanding the Model Component} +* {@link dev_guide.mvc.understanding_controller Understanding the Controller Component} +* {@link dev_guide.mvc.understanding_view Understanding the View Component} + + + diff --git a/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc b/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc new file mode 100644 index 00000000..18e74edc --- /dev/null +++ b/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc @@ -0,0 +1,323 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: About MVC in Angular: Understanding the Controller Component +@description + + +In angular, a controller is a JavaScript function (type/class) that is used to augment instances of +angular {@link dev_guide.scopes Scope}, excluding the root scope. When you or angular create a new +child scope object via the {@link api/angular.scope.$new scope.$new} API , there is an +option to pass in a controller as a method argument. This will tell angular to associate the +controller with the new scope and to augment its behavior. + + +Use controllers to: + + +- Set up the initial state of a scope object. +- Add behavior to the scope object. + + +# Setting up the initial state of a scope object + + +Typically, when you create an application you need to set up an initial state for an angular scope. + + +Angular applies (in the sense of JavaScript's `Function#apply`) the controller constructor function +to a new angular scope object, which sets up an initial scope state. This means that angular never +creates instances of the controller type (by invoking the `new` operator on the controller +constructor). Constructors are always applied to an existing scope object. + + +You set up the initial state of a scope by creating model properties. For example: + + +function GreetingCtrl() { + this.greeting = 'Hola!'; +} + + +The `GreetingCtrl` controller creates a `greeting` model which can be referred to in a template. + + +When a controller function is applied to an angular scope object, the `this` of the controller +function becomes the scope of the angular scope object, so any assignment to `this` within the +controller function happens on the angular scope object. + + +# Adding Behavior to a Scope Object + + +Behavior on an angular scope object is in the form of scope method properties available to the +template/view. This behavior interacts with and modifies the application model. + + +As discussed in the {@link dev_guide.mvc.understanding_model Model} section of this guide, any +objects (or primitives) assigned to the scope become model properties. Any functions assigned to +the scope, along with any prototype methods of the controller type, become functions available in +the template/view, and can be invoked via angular expressions and `ng:` event handlers (e.g. {@link +api/angular.directive.ng:click ng:click}). These controller methods are always evaluated within the +context of the angular scope object that the controller function was applied to (which means that +the `this` keyword of any controller method is always bound to the scope that the controller +augments). This is how the second task of adding behavior to the scope is accomplished. + + + + +# Using Controllers Correctly + + +In general, a controller shouldn't try to do too much. It should contain only the business logic +needed for a single view. + + +The most common way to keep controllers slim is by encapsulating work that doesn't belong to +controllers into services and then using these services in controllers via dependency injection. +This is discussed in the {@link dev_guide.di Dependency Injection} {@link dev_guide.services +Services} sections of this guide. + + +Do not use controllers for: + + +- Any kind of DOM manipulation — Controllers should contain only business logic. DOM +manipulation—the presentation logic of an application—is well known for being hard to test. +Putting any presentation logic into controllers significantly affects testability of the business +logic. Angular offers {@link dev_guide.templates.databinding} for automatic DOM manipulation. If +you have to perform your own manual DOM manipulation, encapsulate the presentation logic in {@link +dev_guide.compiler.widgets widgets} and {@link dev_guide.compiler.directives directives}. +- Input formatting — Use {@link dev_guide.templates.formatters angular formatters} instead. +- Output filtering — Use {@link dev_guide.templates.filters angular filters} instead. +- Run stateless or stateful code shared across controllers — Use {@link dev_guide.services angular +services} instead. +- Instantiate or manage the life-cycle of other components (for example, to create service +instances). + + + + +# Associating Controllers with Angular Scope Objects + + +You can associate controllers with scope objects explicitly via the {@link api/angular.scope.$new +scope.$new} api or implicitly via the {@link api/angular.directive.@ng:controller ng:controller +directive} or {@link api/angular.service.$route $route service}. + + + + +## Controller Constructor and Methods Example + + +To illustrate how the controller component works in angular, let's create a little app with the +following components: + + +- A {@link dev_guide.templates template} with two buttons and a simple message +- A model consisting of a string named `spice` +- A controller with two functions that set the value of `spice` + + +The message in our template contains a binding to the `spice` model, which by default is set to the +string "very". Depending on which button is clicked, the `spice` model is set to `chili` or +`jalapeño`, and the message is automatically updated by data-binding. + + + + +## A Spicy Controller Example + + +
+
+ 
+ 
+ 

The food is {{spice}} spicy!

+ + + +function SpicyCtrl() { + this.spice = 'very'; + this.chiliSpicy = function() { + this.spice = 'chili'; + } +} + + +SpicyCtrl.prototype.jalapenoSpicy = function() { + this.spice = 'jalapeño'; +} +
+ + +Things to notice in the example above: + + +- The `ng:controller` directive is used to (implicitly) create a scope for our template, and the +scope is augmented (managed) by the `SpicyCtrl` controller. +- `SpicyCtrl` is just a plain JavaScript function. As an (optional) naming convention the name +starts with capital letter and ends with "Ctrl" or "Controller". +- The JavaScript keyword `this` in the `SpicyCtrl` function is bound to the scope that the +controller augments. +- Assigning a property to `this` creates or updates the model. +- Controller methods can be created through direct assignment to scope (the `chiliSpicy` method) or +as prototype methods of the controller constructor function (the `jalapenoSpicy` method) +- Both controller methods are available in the template (for the `body` element and and its +children). + + +Controller methods can also take arguments, as demonstrated in the following variation of the +previous example. + + +## Controller Method Arguments Example + + +
+
+ 
+ 
+ 
+ 

The food is {{spice}} spicy!

+ + + +function SpicyCtrl() { + this.spice = 'very'; + this.spicy = function(spice) { + this.spice = spice; + } +} +
+ + +Notice that the `SpicyCtrl` controller now defines just one method called `spicy`, which takes one +argument called `spice`. The template then refers to this controller method and passes in a string +constant `'chili'` in the binding for the first button and a model property `spice` (bound to an +input box) in the second button. + + + + +## Controller Inheritance Example + + +Controller inheritance in angular is based on {@link api/angular.scope Scope} inheritance. Let's +have a look at an example: + + +
+
+ 

Good {{timeOfDay}}, {{name}}!

+
+

Good {{timeOfDay}}, {{name}}!

+

Good {{timeOfDay}}, {{name}}!

+ + + +function MainCtrl() { + this.timeOfDay = 'morning'; + this.name = 'Nikki'; +} + + +function ChildCtrl() { + this.name = 'Mattie'; +} + + +function BabyCtrl() { + this.timeOfDay = 'evening'; + this.name = 'Gingerbreak Baby'; +} +
+ + +Notice how we nested three `ng:controller` directives in our template. This template construct will +result in 4 scopes being created for our view: + + +- The root scope +- The `MainCtrl` scope, which contains `timeOfDay` and `name` models +- The `ChildCtrl` scope, which shadows the `name` model from the previous scope and inherits the +`timeOfDay` model +- The `BabyCtrl` scope, which shadows both the `timeOfDay` model defined in `MainCtrl` and `name` +model defined in the ChildCtrl + + +Inheritance works between controllers in the same way as it does with models. So in our previous +examples, all of the models could be replaced with controller methods that return string values. + + +Note: Standard prototypical inheritance between two controllers doesn't work as one might expect, +because as we mentioned earlier, controllers are not instantiated directly by angular, but rather +are applied to the scope object. + + + + +## Testing Controllers + + +The way to test a controller depends upon how complicated the controller is. + + +- If your controller doesn't use DI or scope methods — create the controller with the `new` +operator and test away. For example: + + +Controller Function: +
+function myController() {
+   this.spices = [{"name":"pasilla", "spiciness":"mild"},
+                  {"name":"jalapeno", "spiceiness":"hot hot hot!"},
+                  {"name":"habanero", "spiceness":"LAVA HOT!!"}];
+
+
+   this.spice = "habanero";
+}
+
+ + +Controller Test: +
+describe('myController function', function() {
+
+
+  describe('myController', function(){
+    var ctrl;
+
+
+    beforeEach(function() {
+      ctrl = new myController();
+    });
+
+
+    it('should create "spices" model with 3 spices', function() {
+      expect(ctrl.spices.length).toBe(3);
+    });
+
+
+    it('should set the default value of spice', function() {
+      expect(ctrl.spice).toBe('habanero');
+    });
+  });
+});
+
+ + +- If your controller does use DI or scope methods — create a root scope, then create the controller +in the root scope with `scope.$new(MyController)`. Test the controller using `$eval`, if necessary. +- If you need to test a nested controller that depends on its parent's state — create a root scope, +create a parent scope, create a child scope, and test the controller using $eval if necessary. + + + + +## Related Topics + + +* {@link dev_guide.mvc About MVC in Angular} +* {@link dev_guide.mvc.understanding_model Understanding the Model Component} +* {@link dev_guide.mvc.understanding_view Understanding the View Component} diff --git a/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc b/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc new file mode 100644 index 00000000..15d8bcb2 --- /dev/null +++ b/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc @@ -0,0 +1,96 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: About MVC in Angular: Understanding the Model Component +@description + + +Depending on the context of the discussion in angular documentation, the term _model_ can refer to +either a single object representing one entity (for example, a model called "phones" with its value +being an array of phones) or the entire data model for the application (all entities). + + +In angular, a model is any data that is reachable as a property of an angular {@link +dev_guide.scopes Scope} object. The name of the property is the model identifier and the value is +any JavaScript object (including arrays and primitives). + + +The only requirement for a JavaScript object to be a model in angular is that the object must be +referenced by an angular scope as a property of that scope object. This property reference can be +created explicitly or implicitly. + + +You can create models by explicitly creating scope properties referencing JavaScript objects in the +following ways: + + +* Make a direct property assignment to the scope object in JavaScript code; this most commonly +occurs in controllers: + + + function MyCtrl() { + // create property 'foo' on the MyCtrl's scope + // and assign it an initial value 'bar' + this.foo = 'bar'; + } + + +* Use an {@link dev_guide.expressions angular expression} with an assignment operator in templates: + + + + + +* Use {@link api/angular.directive.ng:init ng:init directive} in templates (for toy/example apps +only, not recommended for real applications): + + + + + +Angular creates models implicitly (by creating a scope property and assigning it a suitable value) +when processing the following template constructs: + + +* Form input, select, and textarea elements: + + + + + The code above creates a model called "query" on the current scope with the value set to "fluffy +cloud". + + +* An iterator declaration in {@link api/angular.widget.@ng:repeat ng:repeater}: + + +

+ + + The code above creates one child scope for each item in the "phones" array and creates a "phone" +object (model) on each of these scopes with its value set to the value of "phone" in the array. + + +In angular, a JavaScript object stops being a model when: + + +* No angular scope contains a property that references the object. + + +* All angular scopes that contain a property referencing the object become stale and eligible for +garbage collection. + + +The following illustration shows a simple data model created implicitly from a simple template: + + + + + + + +## Related Topics + + +* {@link dev_guide.mvc About MVC in Angular} +* {@link dev_guide.mvc.understanding_controller Understanding the Controller Component} +* {@link dev_guide.mvc.understanding_view Understanding the View Component} diff --git a/docs/content/guide/dev_guide.mvc.understanding_view.ngdoc b/docs/content/guide/dev_guide.mvc.understanding_view.ngdoc new file mode 100644 index 00000000..ff202688 --- /dev/null +++ b/docs/content/guide/dev_guide.mvc.understanding_view.ngdoc @@ -0,0 +1,29 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: About MVC in Angular: Understanding the View Component +@description + + +In angular, the view is the DOM loaded and rendered in the browser, after angular has transformed +the DOM based on information in the template, controller and model. + + + + + +In the angular implementation of MVC, the view has knowledge of both the model and the controller. +The view knows about the model where two-way data-binding occurs. The view has knowledge of the +controller through angular directives, such as {@link api/angular.directive.@ng:controller +ng:controller} and {@link api/angular.widget.ng:view ng:view}, and through bindings of this form: +`{{someControllerFunction()}}`. In these ways, the view can call functions in an associated +controller function. + + + + +## Related Topics + + +* {@link dev_guide.mvc About MVC in Angular} +* {@link dev_guide.mvc.understanding_model Understanding the Model Component} +* {@link dev_guide.mvc.understanding_controller Understanding the Controller Component} diff --git a/docs/content/guide/dev_guide.overview.ngdoc b/docs/content/guide/dev_guide.overview.ngdoc new file mode 100644 index 00000000..7eb56470 --- /dev/null +++ b/docs/content/guide/dev_guide.overview.ngdoc @@ -0,0 +1,288 @@ +@ngdoc overview +@name Developer Guide: Overview +@description + + + + +# What Is Angular? + + +The short answer: angular is a new, powerful, client-side technology that makes it much easier for +you to create dynamic web sites and complex web apps, all without leaving the comfort of your HTML +/ JavaScript home. + + +The long answer: it depends on where you're coming from... + + +* If you're a web designer, you might perceive angular to be a sweet {@link dev_guide.templates +templating} system, that doesn't get in your way and provides you with lots of nice built-ins that +make it easier to do what you want to do. + + +* If you're a web developer, you might be thrilled that angular functions as an excellent web +framework, one that assists you all the way through the development cycle. + + +* If you want to go deeper, you can immerse yourself in angular's extensible HTML {@link +dev_guide.compiler compiler} that runs in your browser. The angular compiler teaches your browser +new tricks. + + +Angular is not just a templating system, but you can create fantastic templates with it. Angular is +not just a web framework, but it features a very nice framework. Angular is not just an extensible +HTML compiler, but the compiler is at the core of Angular. Angular includes all of these +components, along with others. Angular is far greater than the sum of its parts. It is a new, +better way to develop web applications! + + + + +## An Introductory Angular Example + + +Let's say that you are a web designer, and you've spent many thous — erm, hundreds of hours +designing web sites. But at this point, the thought of manipulating the DOM, writing listeners and +input validators, all just to implement a simple form? No. You either don't want to go there in +the first place or you've been there and the thrill is gone. + + +So look over the following simple example written using angular. Note that it features only the +templating aspect of angular, but this should suffice for now to quickly demonstrate how much +easier a web developer's life can if they're using angular: + + + + + Invoice: +
+
+ + + + + + + +
QuantityCost
+
+ Total: {{qty * cost | currency}} +
+ +
+ + +Try out the Live Preview above, and then let's walk through the example and describe what's going +on. + + +In the `` tag, we add an attribute to let the browser know about the angular namespace: + + + + + +This ensures angular runs nicely in all major browsers. + + +In the `` + + +From the `name` attribute of the `` tags, angular automatically sets up two-way data +binding, and we also demonstrate some easy input validation: + + + Quantity: + Cost: + + +These input widgets look normal enough, but consider these points: + + +* When this page loaded, angular bound the names of the input widgets (`qty` and `cost`) to +variables of the same name. Think of those variables as the "Model" component of the +Model-View-Controller design pattern. +* Note the angular directives, {@link api/angular.widget.@ng:validate ng:validate} and {@link +api/angular.widget.@ng:required ng:required}. You may have noticed that when you enter invalid data +or leave the the input fields blank, the borders turn red color, and the display value disappears. +These `ng:` directives make it easier to implement field validators than coding them in JavaScript, +no? Yes. + + +And finally, the mysterious `{{ double curly braces }}`: + + + Total: {{qty * cost | currency}} + + +This notation, `{{ _expression_ }}`, is a bit of built-in angular {@link dev_guide.compiler.markup +markup}, a shortcut for displaying data to the user. The expression within curly braces gets +transformed by the angular compiler into an angular directive ({@link api/angular.directive.ng:bind +ng:bind}). The expression itself can be a combination of both an expression and a {@link +dev_guide.templates.filters filter}: `{{ expression | filter }}`. Angular provides filters for +formatting display data. + + +In the example above, the expression in double-curly braces directs angular to, "Bind the data we +got from the input widgets to the display, multiply them together, and format the resulting number +into output that looks like money." + + + + +# The Angular Philosophy + + +Angular is built around the belief that declarative code is better than imperative when it comes to +building UIs and wiring software components together, while imperative code is excellent for +expressing business logic. + + +Not to put too fine a point on it, but if you wanted to add a new label to your application, you +could do so by simply adding text to the HTML template, saving the code, and refreshing your +browser: + + +
+Hello
+
+ + +Or, as in programmatic systems (like {@link http://code.google.com/webtoolkit/ GWT}), you would +have to write the code and then run the code like this: + + +
+var label = new Label();
+label.setText('Hello');
+label.setClass('label');
+parent.addChild(label);
+
+ + +That's one line of markup versus four times as much code. + + + + +## More Angular Philosophy + + +* It is a very good idea to decouple DOM manipulation from app logic. This dramatically improves +the testability of the code. +* It is a really, _really_ good idea to regard app testing as equal in importance to app writing. +Testing difficulty is dramatically affected by the way the code is structured. +* It is an excellent idea to decouple the client side of an app from the server side. This allows +development work to progress in parallel, and allows for reuse of both sides. +* It is very helpful indeed if the framework guides developers through the entire journey of +building an app: from designing the UI, through writing the business logic, to testing. +* It is always good to make common tasks trivial and difficult tasks possible. + + +Now that we're homing in on what angular is, perhaps now would be a good time to list a few things +that angular is not: + + +* It's not a Library. You don't just call its functions, although it does provide you with some +utility APIs. +* It's not a DOM Manipulation Library. Angular uses jQuery to manipulate the DOM behind the scenes, +rather than give you functions to manipulate the DOM yourself. +* It's not a Widget Library. There are lots of existing widget libraries that you can integrate +with angular. +* It's not "Just Another Templating System". A part of angular is a templating system. The +templating subsystem of angular is different from the traditional approach for these reasons: + * It Uses HTML/CSS syntax: This makes it easy to read and can be edited with existing HTML/CSS +authoring tools. + * It Extends HTML vocabulary: Angular allows you to create new HTML tags, which expand into +dynamic UI components. + * It Executes in the browser: Removes the round trip to the server for many operations and +creates instant feedback for users as well as developers. + * It Has Bidirectional data binding: The model is the single source of truth. Programmatic +changes to the model are automatically reflected in the view. Any changes by the user to the view +are automatically reflected in the model. + + + + +# Why You Want Angular + + +Angular frees you from the following pain: + + +* **Registering callbacks:** Registering callbacks clutters your code, making it hard to see the +forest for the trees. Removing common boilerplate code such as callbacks is a good thing. It vastly +reduces the amount of JavaScript coding _you_ have to do, and it makes it easier to see what your +application does. +* **Manipulating HTML DOM programatically:** Manipulating HTML DOM is a cornerstone of AJAX +applications, but it's cumbersome and error-prone. By declaratively describing how the UI should +change as your application state changes, you are freed from low level DOM manipulation tasks. Most +applications written with angular never have to programatically manipulate the DOM, although you +can if you want to. +* **Marshaling data to and from the UI:** CRUD operations make up the majority of AJAX +applications. The flow of marshaling data from the server to an internal object to an HTML form, +allowing users to modify the form, validating the form, displaying validation errors, returning to +an internal model, and then back to the server, creates a lot of boilerplate code. Angular +eliminates almost all of this boilerplate, leaving code that describes the overall flow of the +application rather than all of the implementation details. +* **Writing tons of initialization code just to get started:** Typically you need to write a lot of +plumbing just to get a basic "Hello World" AJAX app working. With angular you can bootstrap your +app easily using services, which are auto-injected into your application in a {@link +http://code.google.com/p/google-guice/ Guice}-like dependency-injection style. This allows you to +get started developing features quickly. As a bonus, you get full control over the initialization +process in automated tests. + + + + +# Watch a Presentation About Angular + + +Here is an early presentation on angular, but note that substantial development has occurred since +the talk was given in July of 2010. + + + + + + + + + + +{@link + +https://docs.google.com/present/edit?id=0Abz6S2TvsDWSZDQ0OWdjaF8yNTRnODczazdmZg&hl=en&authkey=CO-b7oID + +Presentation} +| +{@link + +https://docs.google.com/document/edit?id=1ZHVhqC0apbzPRQcgnb1Ye-bAUbNJ-IlFMyPBPCZ2cYU&hl=en&authkey=CInnwLYO + +Source} diff --git a/docs/content/guide/dev_guide.scopes.controlling_scopes.ngdoc b/docs/content/guide/dev_guide.scopes.controlling_scopes.ngdoc new file mode 100644 index 00000000..ca63cbc3 --- /dev/null +++ b/docs/content/guide/dev_guide.scopes.controlling_scopes.ngdoc @@ -0,0 +1,50 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Scopes: Applying Controllers to Scopes +@description + + +When a controller function is applied to a scope, the scope is augmented with the behavior defined +in the controller. The end result is that the scope behaves as if it were the controller: + + +
+var scope = angular.scope();
+scope.salutation = 'Hello';
+scope.name = 'World';
+
+
+expect(scope.greeting).toEqual(undefined);
+
+
+scope.$watch('name', function(){
+this.greeting = this.salutation + ' ' + this.name + '!';
+});
+
+
+expect(scope.greeting).toEqual('Hello World!');
+scope.name = 'Misko';
+// scope.$eval() will propagate the change to listeners
+expect(scope.greeting).toEqual('Hello World!');
+
+
+scope.$eval();
+expect(scope.greeting).toEqual('Hello Misko!');
+
+ + + + +## Related Topics + + +* {@link dev_guide.scopes Angular Scope Objects} +* {@link dev_guide.scopes.understanding_scopes Understanding Angular Scopes} +* {@link dev_guide.scopes.working_scopes Working With Angular Scopes} +* {@link dev_guide.scopes.updating_scopes Updating Angular Scopes} + + +## Related API + + +* {@link api/angular.scope Angular Scope API} diff --git a/docs/content/guide/dev_guide.scopes.ngdoc b/docs/content/guide/dev_guide.scopes.ngdoc new file mode 100644 index 00000000..730ac348 --- /dev/null +++ b/docs/content/guide/dev_guide.scopes.ngdoc @@ -0,0 +1,51 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Angular Scopes +@description + + + + +An angular scope is a JavaScript type defined by angular. Instances of this type are objects that +serve as the context within which all model and controller methods live and get evaluated. + + +Angular links scope objects to specific points in a compiled (processed) template. This linkage +provides the contexts in which angular creates data-bindings between the model and the view. You +can think of angular scope objects as the medium through which the model, view, and controller +communicate. + + +In addition to providing the context in which data is evaluated, angular scope objects watch for +model changes. The scope objects also notify all components interested in any model changes (for +example, functions registered through {@link api/angular.scope.$watch $watch}, bindings created by +{@link api/angular.directive.ng:bind ng:bind}, or HTML input elements). + + +Angular scope objects are responsible for: + + +* Gluing the model, controller and view template together. +* Providing the mechanism to watch for model changes ({@link api/angular.scope.$watch}). +* Notifying interested components when the model changes ({@link api/angular.scope.$eval}). +* Providing the context in which all controller functions and angular expressions are evaluated. + + + + +## Related Topics + + +* {@link dev_guide.scopes.understanding_scopes Understanding Scopes} +* {@link dev_guide.scopes.working_scopes Working With Scopes} +* {@link dev_guide.scopes.controlling_scopes Applying Controllers to Scopes} +* {@link dev_guide.scopes.updating_scopes Updating Scopes} + + +## Related API + + +* {@link api/angular.scope Angular Scope API} + + + diff --git a/docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc b/docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc new file mode 100644 index 00000000..b258f867 --- /dev/null +++ b/docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc @@ -0,0 +1,83 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Scopes: Understanding Scopes +@description + + +Angular automatically creates a root scope during initialization, and attaches it to the page's +root DOM element (usually ``). The root scope object, along with any of its child scope +objects, serves as the infrastructure on which your data model is built. The data model (JavaScript +objects, arrays, or primitives) is attached to angular scope properties. Angular binds the property +values to the DOM where bindings are specified in the template. Angular attaches any controller +functions you have created to their respective scope objects. + + + + + +Angular scopes can be nested, so a child scope has a parent scope upstream in the DOM. When you +display an angular expression in the view, angular walks the DOM tree looking in the closest +attached scope object for the specified data. If it doesn't find the data in the closest attached +scope, it looks further up the scope hierarchy until it finds the data. + + +A child scope object inherits properties from its parents. For example, in the following snippet of +code, observe how the value of `name` changes, based on the HTML element it is displayed in: + + + + +
    +
  • + Name = {{name}}! +
  • +
+
Name={{name}}
+
+ + it('should override the name property', function() { + expect(using('.doc-example-live').repeater('li').row(0)). + toEqual(['Igor']); + expect(using('.doc-example-live').repeater('li').row(1)). + toEqual(['Misko']);g/@ + + + expect(using('.doc-example-live').repeater('li').row(2)). + toEqual(['Gail']); + expect(using('.doc-example-live').repeater('li').row(3)). + toEqual(['Kai']); + expect(using('.doc-example-live').element('pre').text()). + toBe('Name=Hank'); + }); + +
+ + +The angular {@link api/angular.widget.@ng:repeat ng:repeat} directive creates a new scope for each +element that it repeats (in this example the elements are list items). In the `