From 924ffafc51cf53ddf97f13ad748bbbf6d80caf13 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Wed, 18 May 2011 12:17:16 -0700 Subject: fixing broken links --- docs/content/api/angular.directive.ngdoc | 6 +- docs/content/cookbook/form.ngdoc | 2 +- docs/content/cookbook/mvc.ngdoc | 2 +- docs/content/guide/compiler.ngdoc | 163 +++++++++++++++++ docs/content/guide/css.ngdoc | 46 +++++ docs/content/guide/di.ngdoc | 304 +++++++++++++++++++++++++++++++ docs/content/guide/guide.compiler.ngdoc | 163 ----------------- docs/content/guide/guide.css.ngdoc | 46 ----- docs/content/guide/guide.di.ngdoc | 304 ------------------------------- docs/content/guide/index.ngdoc | 5 +- docs/content/guide/overview.ngdoc | 2 +- docs/content/intro/faq.ngdoc | 2 +- docs/content/tutorial/step_02.ngdoc | 4 +- docs/content/tutorial/step_08.ngdoc | 2 +- docs/content/tutorial/the_end.ngdoc | 2 +- 15 files changed, 525 insertions(+), 528 deletions(-) create mode 100644 docs/content/guide/compiler.ngdoc create mode 100644 docs/content/guide/css.ngdoc create mode 100644 docs/content/guide/di.ngdoc delete mode 100644 docs/content/guide/guide.compiler.ngdoc delete mode 100644 docs/content/guide/guide.css.ngdoc delete mode 100644 docs/content/guide/guide.di.ngdoc (limited to 'docs/content') diff --git a/docs/content/api/angular.directive.ngdoc b/docs/content/api/angular.directive.ngdoc index 9a08e4c7..277830b9 100644 --- a/docs/content/api/angular.directive.ngdoc +++ b/docs/content/api/angular.directive.ngdoc @@ -32,8 +32,8 @@ attribute. So why have two different ways to do the same thing? The answer is th matters, but we have no control over the order in which attributes are read. To solve this we apply attribute widget before the directive. -For example, consider this piece of HTML, which uses the directives `ng:repeat`, `ng:init`, -and `ng:bind`: +For example, consider this piece of HTML, which uses the `ng:repeat`, `ng:init`, +and `ng:bind` widget and directives:
   
Notice that the order of execution matters here. We need to execute -{@link angular.directive.ng:repeat ng:repeat} before we run the +{@link angular.widget.@ng:repeat ng:repeat} before we run the {@link angular.directive.ng:init ng:init} and `ng:bind` on the `
  • ;`. This is because we want to run the `ng:init="a=a+1` and `ng:bind="person"` once for each person in people. We could not have used directive to create this template because attributes are read in an diff --git a/docs/content/cookbook/form.ngdoc b/docs/content/cookbook/form.ngdoc index c9fd9e9a..9ccad1c2 100644 --- a/docs/content/cookbook/form.ngdoc +++ b/docs/content/cookbook/form.ngdoc @@ -91,7 +91,7 @@ allow a user to enter data. # Things to notice -* The user data model is initialized {@link angular.ng:controller controller} and is available in +* The user data model is initialized {@link angular.directive.@ng:controller controller} and is available in the {@link angular.scope scope} with the initial data. * For debugging purposes we have included a debug view of the model to better understand what is going on. diff --git a/docs/content/cookbook/mvc.ngdoc b/docs/content/cookbook/mvc.ngdoc index 94688547..470794b8 100644 --- a/docs/content/cookbook/mvc.ngdoc +++ b/docs/content/cookbook/mvc.ngdoc @@ -122,4 +122,4 @@ no connection between the controller and the view. * The view can call any controller function. * In this example, the `setUrl()` and `readUrl()` functions copy the game state to/from the URL's hash so the browser's back button will undo game steps. See deep-linking. This example calls - {@link angular.Scope.$watch $watch()} to set up a listener that invokes `readUrl()` when needed. + {@link angular.scope.$watch $watch()} to set up a listener that invokes `readUrl()` when needed. diff --git a/docs/content/guide/compiler.ngdoc b/docs/content/guide/compiler.ngdoc new file mode 100644 index 00000000..8896db43 --- /dev/null +++ b/docs/content/guide/compiler.ngdoc @@ -0,0 +1,163 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Compiler +@description + +#Compiler + +While angular might look like just a cool way to build web applications, the core of angular is +actually an HTML compiler. The default HTML transformations that this compiler provides are useful +for building generic apps, but you can also use them to create a domain-specific language for +building specific types of web applications. + +The compiler allows you to add behavior to existing HTML through widgets, directives, and text +markup. + +All of this compilation happens in the web browser, meaning no server is involved. + +# The compilation process +This section describes the steps that angular's HTML compiler goes through. If you use +`ng:autobind` in your application, this compilation process happens automatically when the +application is initialized (e.g. when the user loads the app in a browser). If you're an advanced +user using manual bind mode, you can decide when and how often the compilation happens. + +First, a bit of background of what the compilation step is for. Every type of +{@link angular.widget widget}, {@link angular.markup markup}, and +{@link angular.directive directive} in angular is defined with a compile function, and that +compile function returns an optional link function. Here is the relationship between the two: + + * **compile function** - registers a listener for the widget, markup, or directive's expression. + This function is called exactly once. + * **link function** - sets up the listener. This function can be called multiple times, once per + cloned DOM element (e.g. repeating element). + +Note that angular's built-in widgets, markup, and directives have predefined compile and link +functions that you don't need to modify. However, if you're writing your own widgets, markup, or +directives, you write compile and link functions. Refer to the Compiler API for more information. + +When the HTML compiler compiles a page, it goes through 3 phases: Compile, Create Root Scope, and +Link. + +## 1. Compile Phase + + * Recursively traverse the DOM, depth-first. + * Look for a matching compile function of type widget, then markup, then directive. + * If a compile function is found then execute it. + * When the compile function completes, it should return a link function. Aggregate this link + function with all link functions returned previously by step 1c. + * Repeat steps 1c and 1d for all compile functions found. The result of the compilation step is + the aggregate link function, which comprises all of the individual link functions. + +## 2. Create Root Scope + + * Inject all of the services into the root scope. + +## 3. Link Phase + + * Execute the aggregate link function with the root scope. The aggregate link function calls all + the individual link functions that were generated in the compile phase. + * If there are any clones of the DOM caused by repeating elements, call the link function multiple + times, one for each repeating item. + +Note that while the compile function is executed exactly once, the link function can be executed +multiple times: once for each iteration in a repeater. + +# Example + +The compilation process is best understood through example. Let's say that in your namespace my, +you want to create a new DOM element , which should display a greeting. + +If we want this HTML source: + +
    +
    + +
    +
    + +To produce this DOM: + +
    +
    + + Hello + World! + +
    +
    + +Write this widget definition (assuming you've already declared the my namespace in the page): + + +
    +angular.widget('my:greeter', function(compileElement){
    +  var compiler = this;
    +  compileElement.css('display', 'block');
    +  var salutationExp = compileElement.attr('salutation');
    +  var nameExp = compileElement.attr('name');
    +  return function(linkElement){
    +    var salutationSpan = angular.element('');
    +    linkElement.append(salutationSpan);
    +    linkElement.append(compiler.text(' '));
    +    linkElement.append(nameSpan);
    +    linkElement.append(compiler.text('!'));
    +    this.$watch(salutationExp, function(value){
    +      salutationSpan.text(value);
    +    });
    +    this.$watch(nameExp, function(value){
    +    nameSpan.text(value);
    +    });
    +  };
    +});
    +
    + +Note: For more about widgets, see {@link angular.widget Widget}. + +## Compilation process for this example + +Here are the steps that the compiler goes through for the page that contains this widget definition: + +### Compile Phase + + * Recursively traverse the DOM depth-first. + * Find the angular.widget definition. + * Find and execute the widget's compileElement function, which includes the following steps: + * Add a style element with attribute display: block; to the template DOM so that the browser + knows to treat the element as block element for rendering. (Note: because this style element + was added on the template compileElement, this style is automatically applied to any clones + of the template (i.e. any repeating elements)). + * Extract the salutation and name HTML attributes as angular expressions. + * Return the aggregate link function, which includes just one link function in this example. + +### Link Phase + + * Execute the aggregate link function, which includes the following steps: + * Create a element set to the salutation class + * Create a element set to the name class. + * Add the span elements to the linkElement. (Note: be careful not to add them to the + compileElement, because that's the template.) + * Set up watches on the expressions. When an expression changes, copy the data to the + corresponding spans. + + +## Compiler API + +If you define your own widgets, markup, or directives, you need to access the compiler API. +This section describes the methods on the compiler that you can call. + +Note: As of 12 August 2010, these methods are subject to change. + +Recall that the compile function's this is a reference to the compiler. + + * `compile(element)` - returns `linker` - Invoke new instance of compiler to compile a DOM element + and return a linker function. You can apply the linker function to the original element or a + clone of the original element. The linker function returns a scope. + * `comment(commentText)` - returns `element` - Create a comment element. + * `element(elementName)` - returns `element` - Create an element by name. + * `text(text)` - returns `element` - Create a text element. + * `descend([set])` - returns `descend` - State Get or set the current descend state. If true the + compiler will descend to children elements. + * `directives([set])` - returns `directive` - State Get or set the current directives processing + state. The compiler will process directives only when directives set to true. + diff --git a/docs/content/guide/css.ngdoc b/docs/content/guide/css.ngdoc new file mode 100644 index 00000000..435186c9 --- /dev/null +++ b/docs/content/guide/css.ngdoc @@ -0,0 +1,46 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: CSS +@description + +# CSS +angular includes built-in CSS classes, which in turn have predefined CSS styles. + +# Built-in CSS classes + +## `ng-exception` + +**Usage:** angular applies this class to a DOM element if that element contains an Expression that +threw an exception when evaluated. + +**Styling:** The built-in styling of the ng-exception class displays an error message surrounded +by a solid red border, for example: + + >
    Error message
    + + + +You can try to evaluate malformed expressions in {@link guide.expression expression} to see the +`ng-exception` class' styling. + +## `ng-validation-error` + +**Usage:** angular applies this class to an input widget element if that element's input does not +pass validation. Note that you set the validation criteria on the input widget element using the +Ng:validate or Ng:required directives. + +**Styling:** The built-in styling of the ng-validation-error class turns the border of the input +box red and includes a hovering UI element that includes more details of the validation error. You +can see an example in {@link angular.widget.@ng:validate ng:validate example}. + +## How to override the styles for built-in classes + +To override the styles for these built-in classes, you can do any of the following: + +Download the source code, edit angular.css, and host the source on your own server. +Create a local css file, overriding any styles that you'd like, and link to it from your HTML file +as you normally would: + +
    +
    +
    diff --git a/docs/content/guide/di.ngdoc b/docs/content/guide/di.ngdoc new file mode 100644 index 00000000..6d9a746f --- /dev/null +++ b/docs/content/guide/di.ngdoc @@ -0,0 +1,304 @@ +@workInProgress +@ngdoc overview +@name Developer Guide: Dependency Injection +@description +Dependency injection (DI) is one of the core design patterns in angular and angular applications. DI +allows you to replace almost any part of angular framework or angular application with a custom +implementation, allowing for a highly flexible, maintainable and testable code-base. + +Dependency injection is a very common pattern in Java and other statically typed languages. While +undervalued among JavaScript developers, we feel strongly that DI in JavaScript allows us to achieve +the same benefits as in other languages. + +This document will focus on using dependency injection in angular. It is outside of the scope of +this document to explain details of dependency injection. For more information on this topic, please +refer to these links: + + * {@link http://en.wikipedia.org/wiki/Dependency_injection DI - Wikipedia} + * {@link http://martinfowler.com/articles/injection.html Inversion of Control by Martin Fowler} + * Java + * {@link http://code.google.com/p/google-guice/ Guice} + * {@link http://www.devshed.com/c/a/Java/The-Spring-Framework-Understanding-IoC/ Spring} + * {@link http://picocontainer.org/injection.html picoContainer} + * .NET + * {@link http://msdn.microsoft.com/en-us/magazine/cc163739.aspx MSDN Design Patterns - Dependency Inject} + * {@link http://www.springframework.net/ Spring.NET} + + + +# Dependency Injection in angular + +Angular's dependency injection story begins with a `service`. Service in angular lingo is a +JavaScript object, function, or value that is created by angular's injector via a provided factory +function. The factory function is registered with angular via {@link angular.service}. + +
    +// register a factory for a uniqueId service.
    +angular.service('uniqueId', function(){
    +  // calling the factory function creates the instance function
    +  var id = 0;
    +  return function(){
    +   // calling the counter instance function will return and increment the count
    +   return ++id;
    +  }
    +});
    +
    + +At run-time we can access the `uniqueId` service by looking it up with the service locator like +this: + +
    +// create new root scope which has the injector function `$service()`
    +var scope = angular.scope();
    +
    +// use the `$service` function to look up the service instance function
    +var idGenerator = scope.$service('uniqueId');
    +expect(idGenerator()).toBe(1);
    +
    +// subsequent lookups using the same root scope return the service instance
    +var idGenerator2 = scope.$service('uniqueId');
    +expect(idGenerator).toBe(idGenerator2);
    +
    +// since it is same instance calling idGenerator2 returns 2;
    +expect(idGenerator2()).toBe(2);
    +
    + +The {@link angular.service service} registry seems like a lot of work, so what are the benefits? To +answer this question, it’s important to realize that in large scale applications there are a lot of +services which are often dependent on each other, as in this example: + +
    +angular.service('gadgetFactory', function(uniqueId){
    +  return function(){
    +    return {gadgetId: uniqueId()};
    +  };
    +}, {$inject: ['uniqueId']});
    +
    + +Specifically, notice that the `gadgetFactory` takes `uniqueId` service in its arguments. It also +declares this dependency with the `$inject` property. There are several benefits to this approach: + +* There is no need for a `main` method for an application responsible for instantiating and wiring +these services. The order of service instantiation and wiring can be inferred by examining the +`$inject` annotations. +* It is easy to replace any one service with a different implementation without having to track down +all of the dependencies. This is useful in: + * Tests: when mocks of services are needed (for example using mock {@link angular.service.$xhr}.) + * Customization: when the service bundled with angular does not do exactly what the application +requires. + +More importantly, as we'll soon learn, controllers and other components of angular applications can +also declare their dependencies on services and these will be provided without explicitly looking +them up, but let's not get ahead of ourselves. + +Lastly, it is important to realize that all angular services are singletons – application singletons +to be more precise. This means that there is only one instance of a given service per injector. And +since angular is lethally allergic to the global state, it's absolutely possible to create multiple +injectors each with its own instance of a given service (but that is not typically needed, except in +tests where this property is crucially important). + + +## Service Locator and Scope + +The {@link 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 in your application. +The injector is responsible for caching the instances of services, but this cache is bound to the +scope. This means that different root scopes will 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 get this isolation by having each test create its own separate root scope. + +
    +// crate a root scope
    +var rootScope = angular.scope();
    +// accesss the service locator
    +var myService = rootScope.$service('myService');
    +
    + + + +# Dependency Injection in Controllers + +So far we have been talking about injector as a service locator. This is because we have been +explicitly calling the `$service` method to gain access to the service. Service locator is not +dependency injection since the caller is still responsible for retrieving the dependencies. *True +dependency injection is like Chuck Norris. Chuck does not ask for dependencies; he declares them.* + +The most common place to use dependency injection in angular applications is in +{@link angular.directive.@ng:controller controllers}. Here’s 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 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, such as: + +
    +
    +
    + 
    + 
    +  ...
    + 
    +
    +
    + +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 angular.injector injector} to call the +function with the correct arguments. + + + +# Using Dependency Injection pragmatically + +At times you’ll need to use dependency injection pragmatically, usually when instantiating +controllers manually or writing unit tests. This section explains how to go about it. + +## Retrieving Services + +The simplest form of dependency injection is manual retrieval of scopes, known as service locator. +We say manual because we are asking the injector for an instance of the service (rather then having +the injector provide them to the function). This should be rare since most of the time the dependent +services should be injected into the controller using the `$inject` property array. + +
    +// create a root scope. The root scope will automatically have
    +// `$service` method defined which is configured with all services.
    +// Each instance of root scope will have separate instances of services.
    +var rootScope = angular.scope();
    +
    +// ask for a service explicitly
    +var $window = rootScope.$service('$window');
    +
    + + +## Creating Controllers using Dependency Injection + +In a typical angular application the dependency injection is most commonly used when creating +controllers. +
    +// declare our own service by registering a factory function.
    +angular.service('counter', function(){
    +  var count = 0;
    +  return function(){ return count++; };
    +});
    +
    +// example of a controller which depends on '$window' and 'counter' service
    +// notice that there is an extra unbound parameter 'name' which will not
    +// be injected and must be supplied by the caller.
    +function MyController($window, counter, name) {
    +}
    +
    +// we must declare the dependencies explicitly and in the same order as in
    +// the constructor function. This information is used by the dependency
    +// injection to supply the arguments.
    +// Notice the lack of 'name' argument which makes it an unbound argument.
    +MyController.$inject = ['$window', 'counter'];
    +
    +
    +// Create a root scope which creates the the injector
    +var rootScope = angular.scope();
    +
    +// use the '$new()' method instead of standard 'new' keyword operator to
    +// create an instance of MyController and have the dependency injection
    +// supply the arguments to the controller. The dependency injection only
    +// supplies the bound arguments in `$inject` all addition arguments are
    +// curried from the '$new', in our case 'Alexandria' is the argument which
    +// will be curried to the 'name' argument, while '$window' and 'counter'
    +// are supplied by the dependency injection.
    +var myController = rootScope.$new(MyController, 'Alexandria');
    +// NOTE: the returning controller will be a child scope of parent scope,
    +// in this case the root scope.
    +
    + + +## Calling functions and Curring of arguments + +NOTE: this section is quite lame. The concept it is trying to describe is more closely related to +scope#new than scope#$service. We need a better example to discuss here. Ideally a parent controller +creating a child controller imperatively via $new where the child controller's constructor function +declares a portion of its dependencies via $inject property, but another portion is supplied by the +caller of $new (e.g. parentCtrl.$new(ChildCtrl, configParam1, configParam2); + +Finally, you may need to call functions but have the `$inject` properties of the function be +supplied by the injector. + +
    +// create a root scope with the `$service` injector.
    +var rootScope = angular.scope();
    +
    +// given a function such as
    +function greet ($window, name) {
    +  $window.alert(this.salutation + ' ' + name);
    +}
    +greet.$inject = ['$window'];
    +
    +// you can call function 'greet' such that the injector supplies the
    +// '$window' and the caller supplies the function 'this' and the 'name'
    +// argument.
    +var fnThis = {salutation: 'Hello'}
    +rootScope.$service(greet, fnThis, 'world');
    +
    + + + +# Inferring `$inject` + +**EXPERIMENTAL: 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 an `$inject` annotation on the function, then it calls the `.toString()` +and tries to infer what should be injected using the following rules: + +* any argument starting with `$` is angular service and will be added to `$inject` property array. +* any argument ending with `_` will be added to the `$inject` property array but we strip 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 curring}) + +**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. diff --git a/docs/content/guide/guide.compiler.ngdoc b/docs/content/guide/guide.compiler.ngdoc deleted file mode 100644 index 8896db43..00000000 --- a/docs/content/guide/guide.compiler.ngdoc +++ /dev/null @@ -1,163 +0,0 @@ -@workInProgress -@ngdoc overview -@name Developer Guide: Compiler -@description - -#Compiler - -While angular might look like just a cool way to build web applications, the core of angular is -actually an HTML compiler. The default HTML transformations that this compiler provides are useful -for building generic apps, but you can also use them to create a domain-specific language for -building specific types of web applications. - -The compiler allows you to add behavior to existing HTML through widgets, directives, and text -markup. - -All of this compilation happens in the web browser, meaning no server is involved. - -# The compilation process -This section describes the steps that angular's HTML compiler goes through. If you use -`ng:autobind` in your application, this compilation process happens automatically when the -application is initialized (e.g. when the user loads the app in a browser). If you're an advanced -user using manual bind mode, you can decide when and how often the compilation happens. - -First, a bit of background of what the compilation step is for. Every type of -{@link angular.widget widget}, {@link angular.markup markup}, and -{@link angular.directive directive} in angular is defined with a compile function, and that -compile function returns an optional link function. Here is the relationship between the two: - - * **compile function** - registers a listener for the widget, markup, or directive's expression. - This function is called exactly once. - * **link function** - sets up the listener. This function can be called multiple times, once per - cloned DOM element (e.g. repeating element). - -Note that angular's built-in widgets, markup, and directives have predefined compile and link -functions that you don't need to modify. However, if you're writing your own widgets, markup, or -directives, you write compile and link functions. Refer to the Compiler API for more information. - -When the HTML compiler compiles a page, it goes through 3 phases: Compile, Create Root Scope, and -Link. - -## 1. Compile Phase - - * Recursively traverse the DOM, depth-first. - * Look for a matching compile function of type widget, then markup, then directive. - * If a compile function is found then execute it. - * When the compile function completes, it should return a link function. Aggregate this link - function with all link functions returned previously by step 1c. - * Repeat steps 1c and 1d for all compile functions found. The result of the compilation step is - the aggregate link function, which comprises all of the individual link functions. - -## 2. Create Root Scope - - * Inject all of the services into the root scope. - -## 3. Link Phase - - * Execute the aggregate link function with the root scope. The aggregate link function calls all - the individual link functions that were generated in the compile phase. - * If there are any clones of the DOM caused by repeating elements, call the link function multiple - times, one for each repeating item. - -Note that while the compile function is executed exactly once, the link function can be executed -multiple times: once for each iteration in a repeater. - -# Example - -The compilation process is best understood through example. Let's say that in your namespace my, -you want to create a new DOM element , which should display a greeting. - -If we want this HTML source: - -
    -
    - -
    -
    - -To produce this DOM: - -
    -
    - - Hello - World! - -
    -
    - -Write this widget definition (assuming you've already declared the my namespace in the page): - - -
    -angular.widget('my:greeter', function(compileElement){
    -  var compiler = this;
    -  compileElement.css('display', 'block');
    -  var salutationExp = compileElement.attr('salutation');
    -  var nameExp = compileElement.attr('name');
    -  return function(linkElement){
    -    var salutationSpan = angular.element('');
    -    linkElement.append(salutationSpan);
    -    linkElement.append(compiler.text(' '));
    -    linkElement.append(nameSpan);
    -    linkElement.append(compiler.text('!'));
    -    this.$watch(salutationExp, function(value){
    -      salutationSpan.text(value);
    -    });
    -    this.$watch(nameExp, function(value){
    -    nameSpan.text(value);
    -    });
    -  };
    -});
    -
    - -Note: For more about widgets, see {@link angular.widget Widget}. - -## Compilation process for this example - -Here are the steps that the compiler goes through for the page that contains this widget definition: - -### Compile Phase - - * Recursively traverse the DOM depth-first. - * Find the angular.widget definition. - * Find and execute the widget's compileElement function, which includes the following steps: - * Add a style element with attribute display: block; to the template DOM so that the browser - knows to treat the element as block element for rendering. (Note: because this style element - was added on the template compileElement, this style is automatically applied to any clones - of the template (i.e. any repeating elements)). - * Extract the salutation and name HTML attributes as angular expressions. - * Return the aggregate link function, which includes just one link function in this example. - -### Link Phase - - * Execute the aggregate link function, which includes the following steps: - * Create a element set to the salutation class - * Create a element set to the name class. - * Add the span elements to the linkElement. (Note: be careful not to add them to the - compileElement, because that's the template.) - * Set up watches on the expressions. When an expression changes, copy the data to the - corresponding spans. - - -## Compiler API - -If you define your own widgets, markup, or directives, you need to access the compiler API. -This section describes the methods on the compiler that you can call. - -Note: As of 12 August 2010, these methods are subject to change. - -Recall that the compile function's this is a reference to the compiler. - - * `compile(element)` - returns `linker` - Invoke new instance of compiler to compile a DOM element - and return a linker function. You can apply the linker function to the original element or a - clone of the original element. The linker function returns a scope. - * `comment(commentText)` - returns `element` - Create a comment element. - * `element(elementName)` - returns `element` - Create an element by name. - * `text(text)` - returns `element` - Create a text element. - * `descend([set])` - returns `descend` - State Get or set the current descend state. If true the - compiler will descend to children elements. - * `directives([set])` - returns `directive` - State Get or set the current directives processing - state. The compiler will process directives only when directives set to true. - diff --git a/docs/content/guide/guide.css.ngdoc b/docs/content/guide/guide.css.ngdoc deleted file mode 100644 index 6e028f30..00000000 --- a/docs/content/guide/guide.css.ngdoc +++ /dev/null @@ -1,46 +0,0 @@ -@workInProgress -@ngdoc overview -@name Developer Guide: CSS -@description - -# CSS -angular includes built-in CSS classes, which in turn have predefined CSS styles. - -# Built-in CSS classes - -## `ng-exception` - -**Usage:** angular applies this class to a DOM element if that element contains an Expression that -threw an exception when evaluated. - -**Styling:** The built-in styling of the ng-exception class displays an error message surrounded -by a solid red border, for example: - - >
    Error message
    - - - -You can try to evaluate malformed expressions in {@link angualr.expression expression} to see the -`ng-exception` class' styling. - -## `ng-validation-error` - -**Usage:** angular applies this class to an input widget element if that element's input does not -pass validation. Note that you set the validation criteria on the input widget element using the -Ng:validate or Ng:required directives. - -**Styling:** The built-in styling of the ng-validation-error class turns the border of the input -box red and includes a hovering UI element that includes more details of the validation error. You -can see an example in {@link angular.widget.@ng:validate ng:validate example}. - -## How to override the styles for built-in classes - -To override the styles for these built-in classes, you can do any of the following: - -Download the source code, edit angular.css, and host the source on your own server. -Create a local css file, overriding any styles that you'd like, and link to it from your HTML file -as you normally would: - -
    -
    -
    diff --git a/docs/content/guide/guide.di.ngdoc b/docs/content/guide/guide.di.ngdoc deleted file mode 100644 index 2d1f92eb..00000000 --- a/docs/content/guide/guide.di.ngdoc +++ /dev/null @@ -1,304 +0,0 @@ -@workInProgress -@ngdoc overview -@name Developer Guide: Dependency Injection -@description -Dependency injection (DI) is one of the core design patterns in angular and angular applications. DI -allows you to replace almost any part of angular framework or angular application with a custom -implementation, allowing for a highly flexible, maintainable and testable code-base. - -Dependency injection is a very common pattern in Java and other statically typed languages. While -undervalued among JavaScript developers, we feel strongly that DI in JavaScript allows us to achieve -the same benefits as in other languages. - -This document will focus on using dependency injection in angular. It is outside of the scope of -this document to explain details of dependency injection. For more information on this topic, please -refer to these links: - - * {@link http://en.wikipedia.org/wiki/Dependency_injection DI - Wikipedia} - * {@link http://martinfowler.com/articles/injection.html Inversion of Control by Martin Fowler} - * Java - * {@link http://code.google.com/p/google-guice/ Guice} - * {@link http://www.devshed.com/c/a/Java/The-Spring-Framework-Understanding-IoC/ Spring} - * {@link http://picocontainer.org/injection.html picoContainer} - * .NET - * {@link http://msdn.microsoft.com/en-us/magazine/cc163739.aspx MSDN Design Patterns - Dependency Inject} - * {@link http://www.springframework.net/ Spring.NET} - - - -# Dependency Injection in angular - -Angular's dependency injection story begins with a `service`. Service in angular lingo is a -JavaScript object, function, or value that is created by angular's injector via a provided factory -function. The factory function is registered with angular via {@link angular.service}. - -
    -// register a factory for a uniqueId service.
    -angular.service('uniqueId', function(){
    -  // calling the factory function creates the instance function
    -  var id = 0;
    -  return function(){
    -   // calling the counter instance function will return and increment the count
    -   return ++id;
    -  }
    -});
    -
    - -At run-time we can access the `uniqueId` service by looking it up with the service locator like -this: - -
    -// create new root scope which has the injector function `$service()`
    -var scope = angular.scope();
    -
    -// use the `$service` function to look up the service instance function
    -var idGenerator = scope.$service('uniqueId');
    -expect(idGenerator()).toBe(1);
    -
    -// subsequent lookups using the same root scope return the service instance
    -var idGenerator2 = scope.$service('uniqueId');
    -expect(idGenerator).toBe(idGenerator2);
    -
    -// since it is same instance calling idGenerator2 returns 2;
    -expect(idGenerator2()).toBe(2);
    -
    - -The {@link angular.service service} registry seems like a lot of work, so what are the benefits? To -answer this question, it’s important to realize that in large scale applications there are a lot of -services which are often dependent on each other, as in this example: - -
    -angular.service('gadgetFactory', function(uniqueId){
    -  return function(){
    -    return {gadgetId: uniqueId()};
    -  };
    -}, {$inject: ['uniqueId']});
    -
    - -Specifically, notice that the `gadgetFactory` takes `uniqueId` service in its arguments. It also -declares this dependency with the `$inject` property. There are several benefits to this approach: - -* There is no need for a `main` method for an application responsible for instantiating and wiring -these services. The order of service instantiation and wiring can be inferred by examining the -`$inject` annotations. -* It is easy to replace any one service with a different implementation without having to track down -all of the dependencies. This is useful in: - * Tests: when mocks of services are needed (for example using mock {@link angular.service.$xhr}.) - * Customization: when the service bundled with angular does not do exactly what the application -requires. - -More importantly, as we'll soon learn, controllers and other components of angular applications can -also declare their dependencies on services and these will be provided without explicitly looking -them up, but let's not get ahead of ourselves. - -Lastly, it is important to realize that all angular services are singletons – application singletons -to be more precise. This means that there is only one instance of a given service per injector. And -since angular is lethally allergic to the global state, it's absolutely possible to create multiple -injectors each with its own instance of a given service (but that is not typically needed, except in -tests where this property is crucially important). - - -## Service Locator and Scope - -The {@link 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 in your application. -The injector is responsible for caching the instances of services, but this cache is bound to the -scope. This means that different root scopes will 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 get this isolation by having each test create its own separate root scope. - -
    -// crate a root scope
    -var rootScope = angular.scope();
    -// accesss the service locator
    -var myService = rootScope.$service('myService');
    -
    - - - -# Dependency Injection in Controllers - -So far we have been talking about injector as a service locator. This is because we have been -explicitly calling the `$service` method to gain access to the service. Service locator is not -dependency injection since the caller is still responsible for retrieving the dependencies. *True -dependency injection is like Chuck Norris. Chuck does not ask for dependencies; he declares them.* - -The most common place to use dependency injection in angular applications is in -{@link angular.ng:controller controllers}. Here’s 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 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, such as: - -
    -
    -
    - 
    - 
    -  ...
    - 
    -
    -
    - -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 angular.injector injector} to call the -function with the correct arguments. - - - -# Using Dependency Injection pragmatically - -At times you’ll need to use dependency injection pragmatically, usually when instantiating -controllers manually or writing unit tests. This section explains how to go about it. - -## Retrieving Services - -The simplest form of dependency injection is manual retrieval of scopes, known as service locator. -We say manual because we are asking the injector for an instance of the service (rather then having -the injector provide them to the function). This should be rare since most of the time the dependent -services should be injected into the controller using the `$inject` property array. - -
    -// create a root scope. The root scope will automatically have
    -// `$service` method defined which is configured with all services.
    -// Each instance of root scope will have separate instances of services.
    -var rootScope = angular.scope();
    -
    -// ask for a service explicitly
    -var $window = rootScope.$service('$window');
    -
    - - -## Creating Controllers using Dependency Injection - -In a typical angular application the dependency injection is most commonly used when creating -controllers. -
    -// declare our own service by registering a factory function.
    -angular.service('counter', function(){
    -  var count = 0;
    -  return function(){ return count++; };
    -});
    -
    -// example of a controller which depends on '$window' and 'counter' service
    -// notice that there is an extra unbound parameter 'name' which will not
    -// be injected and must be supplied by the caller.
    -function MyController($window, counter, name) {
    -}
    -
    -// we must declare the dependencies explicitly and in the same order as in
    -// the constructor function. This information is used by the dependency
    -// injection to supply the arguments.
    -// Notice the lack of 'name' argument which makes it an unbound argument.
    -MyController.$inject = ['$window', 'counter'];
    -
    -
    -// Create a root scope which creates the the injector
    -var rootScope = angular.scope();
    -
    -// use the '$new()' method instead of standard 'new' keyword operator to
    -// create an instance of MyController and have the dependency injection
    -// supply the arguments to the controller. The dependency injection only
    -// supplies the bound arguments in `$inject` all addition arguments are
    -// curried from the '$new', in our case 'Alexandria' is the argument which
    -// will be curried to the 'name' argument, while '$window' and 'counter'
    -// are supplied by the dependency injection.
    -var myController = rootScope.$new(MyController, 'Alexandria');
    -// NOTE: the returning controller will be a child scope of parent scope,
    -// in this case the root scope.
    -
    - - -## Calling functions and Curring of arguments - -NOTE: this section is quite lame. The concept it is trying to describe is more closely related to -scope#new than scope#$service. We need a better example to discuss here. Ideally a parent controller -creating a child controller imperatively via $new where the child controller's constructor function -declares a portion of its dependencies via $inject property, but another portion is supplied by the -caller of $new (e.g. parentCtrl.$new(ChildCtrl, configParam1, configParam2); - -Finally, you may need to call functions but have the `$inject` properties of the function be -supplied by the injector. - -
    -// create a root scope with the `$service` injector.
    -var rootScope = angular.scope();
    -
    -// given a function such as
    -function greet ($window, name) {
    -  $window.alert(this.salutation + ' ' + name);
    -}
    -greet.$inject = ['$window'];
    -
    -// you can call function 'greet' such that the injector supplies the
    -// '$window' and the caller supplies the function 'this' and the 'name'
    -// argument.
    -var fnThis = {salutation: 'Hello'}
    -rootScope.$service(greet, fnThis, 'world');
    -
    - - - -# Inferring `$inject` - -**EXPERIMENTAL: 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 an `$inject` annotation on the function, then it calls the `.toString()` -and tries to infer what should be injected using the following rules: - -* any argument starting with `$` is angular service and will be added to `$inject` property array. -* any argument ending with `_` will be added to the `$inject` property array but we strip 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 curring}) - -**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. diff --git a/docs/content/guide/index.ngdoc b/docs/content/guide/index.ngdoc index 2798210d..1a9d2555 100644 --- a/docs/content/guide/index.ngdoc +++ b/docs/content/guide/index.ngdoc @@ -31,7 +31,4 @@ * {@link angular.service Service} - Objects that are wired through dependency injection and then injected into the root scope. * {@link guide.testing Testing} - * service:$browser(mock) -* {@link downloading Downloading} - How to download, compile, and host the angular - environment on your own server. -* {@link guide.contribute Contributing} - How to contribute to angular project. + * service:$browser(mock) \ No newline at end of file diff --git a/docs/content/guide/overview.ngdoc b/docs/content/guide/overview.ngdoc index 61c58435..8723e839 100644 --- a/docs/content/guide/overview.ngdoc +++ b/docs/content/guide/overview.ngdoc @@ -112,7 +112,7 @@ These input widgets look normal enough, but consider these points: of the input widgets (`qty` and `cost`) to variables of the same name. Think of those variables as the "Model" part of the Model-View-Controller design pattern. * Note the angular directives, {@link angular.widget.@ng:validate ng:validate} and {@link -ngular.widget.@ng:required ng:required}. You may have noticed that when you enter invalid data or +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 a plainly irritated red color, and the display value disappears. These `ng:` directives make it easier to implement field validators than coding them in JavaScript, no? Yes. diff --git a/docs/content/intro/faq.ngdoc b/docs/content/intro/faq.ngdoc index dd06d961..2030dfbb 100644 --- a/docs/content/intro/faq.ngdoc +++ b/docs/content/intro/faq.ngdoc @@ -29,7 +29,7 @@ attacks. angular does round-trip escaping on all strings for you. ### Can I download the source, build, and host the angular environment locally? -Yes. See instructions in {@link downloading downloading}. +Yes. See instructions in {@link intro.downloading downloading}. ### Is angular a templating system? diff --git a/docs/content/tutorial/step_02.ngdoc b/docs/content/tutorial/step_02.ngdoc index 04b7b3e0..faad7f0e 100755 --- a/docs/content/tutorial/step_02.ngdoc +++ b/docs/content/tutorial/step_02.ngdoc @@ -133,7 +133,7 @@ data, and logic components: * The name of our controller function (in the JavaScript file `controllers.js`) matches the -{@link angular.directive.ng:controller ng:controller} directive in the `` tag +{@link angular.directive.@ng:controller ng:controller} directive in the `` tag (`PhoneListCtrl`). * We instantiated our data within the scope of our controller function, and our template binding points are located within the block bounded by the `` @@ -145,7 +145,7 @@ the template, model and controller all work together. Angular uses scopes, along information contained in the template, data model, and controller, to keep the model and view separated but in sync. Any changes to the model are reflected in the view; any changes that occur in the view are reflected in the model. To learn more about angular scopes, see the {@link -angular.scopes angular scope documentation}. +angular.scope angular scope documentation}. diff --git a/docs/content/tutorial/step_08.ngdoc b/docs/content/tutorial/step_08.ngdoc index cdedef12..bec7bf6c 100755 --- a/docs/content/tutorial/step_08.ngdoc +++ b/docs/content/tutorial/step_08.ngdoc @@ -37,7 +37,7 @@ Now when you click on a phone on the list, the phone details page with phone-specific information is displayed. -To implement the phone details view we will use {@link angular.services.$xhr $xhr} to fetch our +To implement the phone details view we will use {@link angular.service.$xhr $xhr} to fetch our data, and we'll flesh out the `phone-details.html` view template. diff --git a/docs/content/tutorial/the_end.ngdoc b/docs/content/tutorial/the_end.ngdoc index 5c6bc1ac..8e307998 100644 --- a/docs/content/tutorial/the_end.ngdoc +++ b/docs/content/tutorial/the_end.ngdoc @@ -15,7 +15,7 @@ your development with the {@link https://github.com/angular/angular-seed angular We hope this tutorial was useful to you and that you learned enough about angular to make you want to learn more. We especially hope you are inspired to go out and develop angular web apps of your -own, and that you might be interested in {@link contribute contributing} to angular. +own, and that you might be interested in {@link intro.contribute contributing} to angular. If you have questions or feedback or just want to say "hi", please post a message at {@link https://groups.google.com/forum/#!forum/angular}. -- cgit v1.2.3