From 8e2675029f5ca404a7c649cc161df3ea642d941f Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Sat, 28 Apr 2012 22:45:28 -0700 Subject: chore(docs): re-skin main documentation --- ...ular.module.ng.$compileProvider.directive.ngdoc | 719 --------------------- docs/content/api/index.ngdoc | 62 +- 2 files changed, 3 insertions(+), 778 deletions(-) delete mode 100644 docs/content/api/angular.module.ng.$compileProvider.directive.ngdoc (limited to 'docs/content/api') diff --git a/docs/content/api/angular.module.ng.$compileProvider.directive.ngdoc b/docs/content/api/angular.module.ng.$compileProvider.directive.ngdoc deleted file mode 100644 index a79bd9ba..00000000 --- a/docs/content/api/angular.module.ng.$compileProvider.directive.ngdoc +++ /dev/null @@ -1,719 +0,0 @@ -@ngdoc overview -@name angular.module.ng.$compileProvider.directive -@description - -Directives are a way to teach HTML new tricks. During DOM compilation directives are matched -against the HTML and executed. This allows directives to register behavior, or transform the DOM. - -Angular comes with a built in set of directives which are useful for building web applications but -can be extended such that HTML can be turned into a declarative domain specific language (DSL). - -# Invoking directives from HTML - -Directives have camel cased names such as 'ngBind'. The directive can be invoked by translating -the camel case name into snake case with these special characters `:`, `-`, or `_`. Optionally the -directive can be prefixed with `x-`, or `data-` to make it HTML validator compliant. Here is a -list of some of the possible directive names: `ng:bind`, `ng-bind`, `ng_bind`, `x-ng-bind` and -`data-ng-bind`. - -The directives can be placed in element names, attributes, class names, as well as comments. Here -are some equivalent examples of invoking `myDir`. (However, most directives are restricted to -attribute only.) - -
-  
-  
-  
-  
-
- -Directives can be invoked in many different ways, but are equivalent in the end result as shown in -the following example. - - - - -
- Hello
- <span ng:bind="name">
- <span ng_bind="name">
- <span ng-bind="name">
- <span data-ng-bind="name">
- <span x-ng-bind="name">
-
-
- - it('should load template1.html', function() { - expect(element('div[ng-controller="Ctrl1"] span[ng-bind]').text()).toBe('angular'); - }); - -
- -# String interpolation - -During the compilation process the {@link angular.module.ng.$compile compiler} matches text and -attributes using the {@link angular.module.ng.$interpolate $interpolate} service to see if they -contain embedded expressions. These expressions are registered as {@link -angular.module.ng.$rootScope.Scope#$watch watches} and will update as part of normal {@link -angular.module.ng.$rootScope.Scope#$digest digest} cycle. An example of interpolation is shown -here: - -
-Hello {{username}}!
-
- -# Compilation process, and directive matching - -Compilation of HTML happens in three phases: - - 1. First the HTML is parsed into DOM using the standard browser API. This is important to - realize because the templates must be parsable HTML. This is in contrast to most templating - systems that operate on strings, rather then on DOM elements. - - 2. The compilation of the DOM is performed by the call to {@link angular.module.ng.$compile - $compile()} method. The method traverses the DOM and matches the directives. If a match is found - it is added to the list of directives associated with the given DOM element. Once all directives - for a given DOM element have been identified they are sorted by priority and their `compile()` - functions are executed. The directive compile function has a chance to modify the DOM structure - and is responsible for producing a `link()` function explained next. The {@link - angular.module.ng.$compile $compile()} method returns a combined linking function, which is a - collection of all of the linking functions returned from the individual directive compile - functions. - - 3. Link the template with scope by calling the linking function returned from the previous step. - This in turn will call the linking function of the individual directives allowing them to - register any listeners on the elements and set up any {@link - angular.module.ng.$rootScope.Scope#$watch watches} with the {@link - angular.module.ng.$rootScope.Scope scope}. The result of this is a live binding between the - scope and the DOM. A change in the scope is reflected in the DOM. - -
-  var $compile = ...; // injected into your code
-  var scope = ...;
-
-  var html = '
'; - - // Step 1: parse HTML into DOM element - var template = angular.element(html); - - // Step 2: compile the template - var linkFn = $compile(template); - - // Step 3: link the compiled template with the scope. - linkFn(scope); -
- -## Reasons behind the compile/link separation - -At this point you may wonder why is the compile process broken down to a compile and link phase. -To understand this, lets look at a real world example with repeater: - -
-  Hello {{user}}, you have these actions:
-  
-
- -The short answer is that compile and link separation is needed any time a change in model causes -a change in DOM structure such as in repeaters. - -When the above example is compiled, the compiler visits every node and looks for directives. The -`{{user}}` is an example of {@link angular.module.ng.$interpolate interpolation} directive. {@link -angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat} is another directive. But {@link -angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat} has a dilemma. It needs to be -able to quickly stamp out new `li`s for every `action` in `user.actions`. This means that it needs -to save a clean copy of the `li` element for cloning purposes and as new `action`s are inserted, -the template `li` element needs to be cloned and inserted into `ul`. But cloning the `li` element -is not enough. It also needs to compile the `li` so that its directives such as -`{{action.descriptions}}` evaluate against the right {@link angular.module.ng.$rootScope.Scope -scope}. A naive method would be to simply insert a copy of the `li` elemnt and then compile it. -But compiling on every `li` element clone would be slow, since the compilation requires that we -traverse the DOM tree and look for directives and execute them. If we put the compilation inside a -repeater which needs to unroll 100 items we would quickly run into performance problem. - -The solution is to break the compilation process into two phases the compile phase where all of -the directives are identified and sorted by priority, and a linking phase where any work which -links a specific instance of the {@link angular.module.ng.$rootScope.Scope scope} and the specific -instance of an `li` is performed. - -{@link angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat} works by preventing the -compilation process form descending into `li` element. Instead the {@link -angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat} directive compiles `li` -seperatly. The result of of the `li` element compilation is a linking function which contains all -of the directives contained in the `li` element ready to be attached to a specific clone of `li` -element. At runtime the {@link angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat} -watches the expression and as items are added to the array it clones the `li` element, creates a -new {@link angular.module.ng.$rootScope.Scope scope} for the cloned `li` element and calls the -link function on the cloned `li`. - -Summary: - - * *compile function* - The compile function is relatively rare in directives, since most - directives are concerned with working with a specific DOM element instance rather then - transforming the template DOM element. Any operation which can be shared among the instance of - directives should be moved to the compile function for performance reasons. - - * *link function* - It is rare for the directive not to have a link function. Link function - allows the directive to register listeners to the specific cloned DOM element instance as well - as to copy content into the DOM from the scope. - - -# Writing directives (short version) - -In this example we will build a directive which displays the current time. - - - - -
- Date format:
- Current time is: - - - - - - -# Writing directives (long version) - -The full skeleton of the directive is shown here: - -
-  var myModule = angular.module(...);
-
-  myModule.directive('directiveName', function factory(injectables) {
-    var directiveDefinitionObject = {
-      priority: 0,
-      template: '
', - templateUrl: 'directive.html', - replace: false, - transclude: false, - restrict: 'A', - scope: false, - compile: function compile(tElement, tAttrs, transclude) { - return { - pre: function preLink(scope, iElement, iAttrs, controller) { ... }, - post: function postLink(scope, iElement, iAttrs, controller) { ... } - } - }, - link: function postLink(scope, iElement, iAttrs) { ... } - }; - return directiveDefinitionObject; - }); -
- -In most cases you will not need such fine control and so the above can be simplified. All of the -different parts of this skeleton are explained in following sections. In this section we are -interested only isomers of this skeleton. - -The first step in simplyfing the code is to rely on the deafult values. Therefore the above can be -simplified as: - -
-  var myModule = angular.module(...);
-
-  myModule.directive('directiveName', function factory(injectables) {
-    var directiveDefinitionObject = {
-      compile: function compile(tElement, tAttrs) {
-        return function postLink(scope, iElement, iAttrs) { ... }
-      }
-    };
-    return directiveDefinitionObject;
-  });
-
- -Most directives concern themselves only with instances not with template transformations allowing -further simplification: - -
-  var myModule = angular.module(...);
-
-  myModule.directive('directiveName', function factory(injectables) {
-    return function postLink(scope, iElement, iAttrs) { ... }
-  });
-
- - -## Factory method - -The factory method is responsible for creating the directive. It is invoked only once, when the -{@link angular.module.ng.$compile compiler} matches the directive for the first time. You can -perform any initialization work here. The method is invoked using the {@link -http://localhost:8000/build/docs/api/angular.module.AUTO.$injector#invoke $injector.invoke} which -makes it injectable following all of the rules of injection annotation. - -## Directive Definition Object - -The directive definition object provides instructions to the {@link angular.module.ng.$compile -compiler}. The attributes are: - - * `name` - Name of the current scope. Optional defaults to the name at registration. - - * `priority` - When there are multiple directives defined on a single DOM element, sometimes it - is necessary to specify the order in which the directives are applied. The `priority` is used - to sort the directives before their `compile` functions get called. Higher `priority` goes - first. The order of directives within the same priority is undefined. - - * `terminal` - If set to true then the current `priority` will be the last set of directives - which will execute (any directives at the current priority will still execute - as the order of execution on same `priority` is undefined). - - * `scope` - If set to: - - * `true` - then a new scope will be created for this directive. If multiple directives on the - same element request new scope, only one new scope is created. The new scope rule does not - apply for the root of the template since the root of the template always gets a new scope. - - * `{}` (object hash) - then a new 'isolate' scope is created. The 'isolate' scope differs from - normal scope that it does not prototypically inherit from the parent scope. This is useful - when creating reusable components, which should not accidentally read or modify data in - parent scope.
- The 'isolate' scope takes an object hash which defines a set of local scope properties - derived from the parent scope. These local properties are useful for aliasing values for - templates. Locals definition is a hash of normalized element attribute name to their - corresponding binding strategy. Valid binding strategies are: - - * `attribute` - one time read of element attribute value and save it to widget scope.
- Given `` and widget definition of `scope: {myAttr:'attribute'}`, - then widget scope property `myAttr` will be `"abc"`. - - * `evaluate` - one time evaluation of expression stored in the attribute.
Given - `` and widget definition of `scope: {myAttr:'evaluate'}`, and - parent scope `{name:'angular'}` then widget scope property `myAttr` will be `"angular"`. - - * `bind` - Set up one way binding from the element attribute to the widget scope.
- Given `` and widget definition of `scope: {myAttr:'bind'}`, - and parent scope `{name:'angular'}` then widget scope property `myAttr` will be - `"angular"`, but any changes in the parent scope will be reflected in the widget scope. - - * `accessor` - Set up getter/setter function for the expression in the widget element - attribute to the widget scope.
Given `` and widget definition - of `scope: {myAttr:'prop'}`, and parent scope `{name:'angular'}` then widget scope - property `myAttr` will be a function such that `myAttr()` will return `"angular"` and - `myAttr('new value')` will update the parent scope `name` property. This is useful for - treating the element as a data-model for reading/writing. - - * `expression` - Treat element attribute as an expression to be executed on the parent scope. -
- Given `` and widget definition of `scope: - {myAttr:'expression'}`, and parent scope `{doSomething:function() {}}` then calling the - widget scope function `myAttr` will execute the expression against the parent scope. - - * `controller` - Controller constructor function. The controller is instantiated before the - pre-linking phase and it is shared with other directives if they request it by name (see - `require` attribute). This allows the directives to communicate with each other and augment - each other behavior. The controller is injectable with the following locals: - - * `$scope` - Current scope associated with the element - * `$element` - Current element - * `$attrs` - Current attributes obeject for the element - * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope: - `function(cloneLinkingFn)`. - - * `require` - Require another controller be passed into current directive linking function. The - `require` takes a name of the directive controller to pass in. If no such controller can be - found an error is raised. The name can be prefixed with: - - * `?` - Don't raise an error. This makes the require dependency optional. - * `^` - Look for the controller on parent elements as well. - - - * `inject` (object hash) - Specifies a way to inject bindings into a controller. Injection - definition is a hash of normalized element attribute names to their corresponding binding - strategy. Valid binding strategies are: - - * `attribute` - inject attribute value.
- Given `` and widget definition of `inject: {myAttr:'attribute'}`, then - `myAttr` will inject `"abc"`. - - * `evaluate` - inject one time evaluation of expression stored in the attribute.
- Given `` and widget definition of `inject: {myAttr:'evaluate'}`, and - parent scope `{name:'angular'}` then `myAttr` will inject `"angular"`. - - * `accessor` - inject a getter/setter function for the expression in the widget element - attribute to the widget scope.
- Given `` and widget definition of `inject: {myAttr:'prop'}`, and - parent scope `{name:'angular'}` then injecting `myAttr` will inject a function such - that `myAttr()` will return `"angular"` and `myAttr('new value')` will update the parent - scope `name` property. This is usefull for treating the element as a data-model for - reading/writing. - - * `expression` - Inject expression function.
- Given `` and widget definition of - `inject: {myAttr:'expression'}`, and parent scope `{doSomething:function() {}}` then - injecting `myAttr` will inject a function which when called will execute the expression - against the parent scope. - - * `restrict` - String of subset of `EACM` which restricts the directive to a specific directive - declaration style. If omitted directives are allowed on attributes only. - - * `E` - Element name: `` - * `A` - Attribute: `
` - * `C` - Class: `
` - * `M` - Comment: `` - - * `template` - replace the current element with the contents of the HTML. The replacement process - migrates all of the attributes / classes from the old element to the new one. See Creating - Widgets section below for more information. - - * `templateUrl` - Same as `template` but the template is loaded from the specified URL. Because - the template loading is asynchronous the compilation/linking is suspended until the template - is loaded. - - * `replace` - if set to `true` then the template will replace the current element, rather then - append the template to the element. - - * `transclude` - compile the content of the element and make it available to the directive. - Typically used with {@link api/angular.module.ng.$compileProvider.directive.ngTransclude - ngTransclude}. The advantage of transclusion is that the linking function receives a - transclusion function which is pre-bound to the correct scope. In a typical setup the widget - creates an `isolate` scope, but the transclusion is not a child, but a sibling of the `isolate` - scope. This makes it possible for the widget to have private state, and the transclusion to - be bound to the parent (pre-`isolate`) scope. - - * `true` - transclude the content of the directive. - * `'element'` - transclude the whole element including any directives defined at lower priority. - - - * `compile`: This is the compile function described in the section below. - - * `link`: This is the link function described in the section below. This property is used only - if the `compile` property is not defined. - -## Compile function - -
-  function compile(tElement, tAttrs, transclude) { ... }
-
- -Compile function deals with transforming the template DOM. Since most directives do not do -template transformation, it is not used often. Examples which require compile functions are -directives which transform template DOM such as {@link -angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat} or load the contents -asynchronously such as {@link angular.module.ng.$compileProvider.directive.ngView ngView}. The -compile functions takes the following arguments. - - * `tElement` - template element - The element where the directive has been declared. It is - safe to do template transformation on the element and child elements only. - - * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared - between all directive compile functions. See {@link - #Attributes Attributes} - - * `transclude` - A transclude linking function: `function(scope, cloneLinkingFn)`. - -NOTE: The template instance and the link instance may not be the same objects if the template has -been cloned. For this reason it is not safe in the compile function to do anything other the DOM -transformation that applies to all DOM clones. Specifically, DOM listener registration should be -done in a linking function rather than in a compile function. - -A compile function can have a return value which can be either a function or an object. - -* returning a function - is equivalent to registering the linking function via the `link` property - of the config object when the compile function is empty. - -* returning an object with function(s) registered via `pre` and `post` properties - allows you to - control when a linking function should be called during the linking phase. See info about - pre-linking and post-linking functions below. - - -## Linking function - -
-  function link(scope, iElement, iAttrs, controller) { ... }
-
- -Link function is responsible for registering DOM listeners as well as updating the DOM. It is -executed after the template has been cloned. This is where most of the directive logic will be -put. - - * `scope` - {@link angular.module.ng.$rootScope.Scope Scope} - The scope to be used by the - directive for registering {@link angular.module.ng.$rootScope.Scope#$watch watches}. - - * `iElement` - instance element - The element where the directive is to be used. It is safe to - manipulate the children of the element only in `postLink` function since the children have - already been linked. - - * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared - between all directive linking functions. See {@link #Attributes Attributes} - - * `controller` - a controller instance - A controller instance if at least one directive on the - element defines a controller. The controller is shared among all the directives, which allows - the directives to use the controllers as a communication channel. - - - -### Pre-linking function - -Executed before the child elements are linked. Not safe to do DOM transformation since the -compiler linking function will fail to locate the correct elements for linking. - -### Post-linking function - -Executed after the child elements are linked. Safe to do DOM transformation in here. - - -## Attributes - -The attributes object - passed as a parameter in the link() or compile() functions - is a way of -accessing: - - * *normalized attribute names:* Since a directive such as 'ngBind' can be expressed in many ways - sucha s as 'ng:bind', or 'x-ng-bind', the attributes object allows for a normalize accessed to - the attributes. - - * *directive inter-communication:* All directives share the same instance of the attributes - object which allows the directives to use the attributes object as inter directive - communication. - - * *supports interpolation:* Interpolation attributes are assigned to the attribute object - allowing other directives to read the interpolated value. - - * *observing interpolated attributes:* Use `$observe` to observe the value changes of attributes - that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also - the only way to easily get the actual value because during the linking phase the interpolation - hasn't been evaluated yet and so the value is at this time set to `undefined`. - -
-function linkingFn(scope, elm, attrs, ctrl) {
-  // get the attribute value
-  console.log(attrs.ngModel);
-
-  // change the attribute
-  attrs.$set('ngModel', 'new value');
-
-  // observe changes to interpolated attribute
-  attrs.$observe('ngModel', function(value) {
-    console.log('ngModel has changed value to ' + value);
-  });
-}
-
- - -# Understanding Transclusion and Scopes - -It is often desirable to have reusable components. Below is a pseudo code showing how a simplified -dialog component may work. - -
-  
- - - Body goes here: {{username}} is {{title}}. - -
- -Clicking on the "show" button will open the dialog. The dialog will have a title, which is -data bound to `username`, and it will also have a body which we would like to transclude -into the dialog. - -Here is an example of what the template definition for the `dialog` widget may look like. - -
-  
-

{{title}}

-
- -
-
- -This will not render properly, unless we do some scope magic. - -The first issue we have to solve is that the dialog box template expect `title` to be defined, but -the place of instantiation would like to bind to `username`. Furthermore the buttons expect `onOk` -as well as `onCancel` functions to be present in the scope. This limits the usefulness of the -widget. To solve the mapping issue we use the `locals` to create local variables which the template -expects as follows: - -
-  scope: {
-    title: 'bind',          // set up title to accept data-binding
-    onOk: 'expression',     // create a delegate onOk function
-    onCancel: 'expression', // create a delegate onCancel function
-    show: 'accessor'        // create a getter/setter function for visibility.
-  }
-
- -Creating local properties on widget scope creates two problems: - - 1. isolation - if the user forgets to set `title` attribute of the dialog widget the dialog - template will bind to parent scope property. This is unpredictable and undesirable. - - 2. transclusion - the transcluded DOM can see the widget locals, which may overwrite the - properties which the transclusion needs for data-binding. In our example the `title` - property of the widget clobbers the `title` property of the transclusion. - - -To solve the issue of lack of isolation, the directive declares a new `isolated` scope. An -isolated scope does not prototypically inherit from the child scope, and therefore we don't have -to worry about accidentally clobbering any properties. - -However 'isolated' scope creates a new problem: if a transcluded DOM is a child of the widget -isolated scope then it will not be able to bind to anything. For this reason the transcluded scope -is a child of the original scope, before the widget created an isolated scope for its local -variables. This makes the transcluded and widget isolated scope siblings. - -This may seem as unexpected complexity, but it gives the widget user and developer the least -surprise. - -Therefore the final directive definition looks something like this: - -
-transclude: true,
-scope: {
-  title: 'bind',          // set up title to accept data-binding
-  onOk: 'expression',     // create a delegate onOk function
-  onCancel: 'expression', // create a delegate onCancel function
-  show: 'accessor'        // create a getter/setter function for visibility.
-}
-
- -# Creating Components - -It is often desirable to replace a single directive with a more complex DOM structure. This -allows the directives to become a short hand for reusable components from which applications -can be built. - -Following is an example of building a reusable widget. - - - - - - -
- Title:
- Text: -
-
{{text}}
-
-
- - it('should bind and open / close', function() { - input('title').enter('TITLE'); - input('text').enter('TEXT'); - expect(element('.title').text()).toEqual('Details: TITLE...'); - expect(binding('text')).toEqual('TEXT'); - - expect(element('.zippy').prop('className')).toMatch(/closed/); - element('.zippy > .title').click(); - expect(element('.zippy').prop('className')).toMatch(/opened/); - }); - -
diff --git a/docs/content/api/index.ngdoc b/docs/content/api/index.ngdoc index 9f1bb398..88e354f5 100644 --- a/docs/content/api/index.ngdoc +++ b/docs/content/api/index.ngdoc @@ -2,62 +2,6 @@ @name API Reference @description -## Angular Compiler API - -* {@link angular.module.ng.$compileProvider.directive Directives} - Angular DOM element attributes -* {@link angular.module.ng.$filter Filters} - Angular output filters -* {@link angular.module.ng.$compile $compile} - Template compiler - -## Angular Scope API - -* {@link angular.module.ng.$rootScope.Scope Scope Object} - Angular scope object - - -## Angular Services & Dependency Injection API - -* {@link angular.module.ng Angular Services} -* {@link angular.injector angular.injector() } - - -## Angular Testing API - -* {@link angular.module.ngMock Testing Mocks API} - Mock objects for testing -* {@link guide/dev_guide.e2e-testing Angular Scenario Runner} - Automated scenario testing -documentation - - -## Angular Utility Functions - -### HTML & DOM Manipulation - -* {@link angular.element angular.element()} - -### Misc - -* {@link angular.bind angular.bind() } -* {@link angular.extend angular.extend() } -* {@link angular.forEach angular.forEach() } -* {@link angular.identity angular.identity() } -* {@link angular.noop angular.noop() } - - -## Type Identification - -* {@link angular.isArray angular.isArray() } -* {@link angular.isDate angular.isDate() } -* {@link angular.isDefined angular.isDefined() } -* {@link angular.isFunction angular.isFunction() } -* {@link angular.isNumber angular.isNumber() } -* {@link angular.isObject angular.isObject() } -* {@link angular.isString angular.isString() } -* {@link angular.isUndefined angular.isUndefined() } - -## Strings - -* {@link angular.lowercase angular.lowercase() } -* {@link angular.uppercase angular.uppercase() } - -### JSON - -* {@link angular.fromJson angular.fromJson() } -* {@link angular.toJson angular.toJson() } +Use the API Refference documentation when you need more information about a specific feature. Check out +{@link guide/ Developer Guide} for AngularJS concepts. If you are new to AngularJS we recomend the +{@link tutorial/ Tutorial}. -- cgit v1.2.3