diff options
| author | Misko Hevery | 2011-02-12 10:13:28 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2011-02-16 01:03:12 -0500 | 
| commit | ef4bb28be13e99f96c9ace5936cf26a174a0e5f0 (patch) | |
| tree | 833057505e430cac064214ac3d55c687338da2a9 /src | |
| parent | 496e6bf9016d33a7cf2f4730d06a8655f01ca5cb (diff) | |
| download | angular.js-ef4bb28be13e99f96c9ace5936cf26a174a0e5f0.tar.bz2 | |
Change API angular.compile(element)([scope], [element/true])
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 51 | ||||
| -rw-r--r-- | src/Compiler.js | 22 | ||||
| -rw-r--r-- | src/widgets.js | 8 | 
3 files changed, 55 insertions, 26 deletions
| diff --git a/src/Angular.js b/src/Angular.js index 9b2c7ea6..9eaeb093 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -793,21 +793,50 @@ function merge(src, dst) {   * @function   *   * @description - * Compiles a piece of HTML or DOM into a {@link angular.scope scope} object. + * Compiles a piece of HTML string or DOM into a view and produces a linking function, which can + * then be used to link {@link angular.scope scope} and the template together. The compilation + * process walks the DOM tree and tries to match DOM elements to {@link angular.markup markup}, + * {@link angular.attrMarkup attrMarkup}, {@link angular.widget widgets}, and + * {@link angular.directive directives}. For each match it executes coresponding markup, \ + * attrMarkup, widget or directive template function and collects the instance functions into a + * single linking function which is then returned. The linking function can then be used + * many-times-over on clones of compiled DOM structure, (For example when compiling + * {@link angular.widget.@ng:repeat repeater} the resulting linking function is called once for + * each item in the collection. The `ng:repeat` does this by cloning the template DOM once for + * each item in collection and then calling the linking function to link the cloned template + * with the a new scope for each item in the collection.) + *     <pre> -    var scope1 = angular.compile(window.document); +    var mvc1 = angular.compile(window.document)(); +    mvc1.view; // compiled view elment +    mvc1.scope; // scope bound to the element -    var scope2 = angular.compile('<div ng:click="clicked = true">click me</div>'); +    var mvc2 = angular.compile('<div ng:click="clicked = true">click me</div>')();     </pre>   * - * @param {string|DOMElement} element Element to compile. - * @param {Object=} parentScope Scope to become the parent scope of the newly compiled scope. - * @returns {Object} Compiled scope object. + * @param {string|DOMElement} element Element or HTML to compile into a template function. + * @returns {function([scope][, element])} a template function which is used to bind element + * and scope. Where: + * + *   * `scope` - {@link angular.scope scope} A scope to bind to. If none specified, then a new + *               root scope is created. + *   * `element` - {@link angular.element element} Element to use as the template. If none + *               specified then reuse the element from `angular.compile(element)`. If `true` + *               then clone the `angular.compile(element)`. The element must be either the same + *               element as `angular.compile(element)` or an identical clone to + *               `angular.compile(element)`. Using an element with differnt structure will cause + *               unpredictable behavior. + * + * Calling the template function returns object: `{scope:?, view:?}`, where: + * + *   * `view` - the DOM element which represents the compiled template. Either same or clone of + *           `element` specifed in compile or template function. + *   * `scope` - scope to which the element is bound to. Either a root scope or scope specified + *           in the template function.   */ -function compile(element, parentScope) { -  var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget), -      $element = jqLite(element); -  return compiler.compile($element)($element, parentScope); +function compile(element) { +  return new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget) +    .compile(element);  }  ///////////////////////////////////////////////// @@ -989,7 +1018,7 @@ function toKeyValue(obj) {  function angularInit(config){    if (config.autobind) {      // TODO default to the source of angular.js -    var scope = compile(window.document, _null, {'$config':config}), +    var scope = compile(window.document)(null, createScope({'$config':config})),          $browser = scope.$service('$browser');      if (config.css) diff --git a/src/Compiler.js b/src/Compiler.js index 6aee40b8..890f2510 100644 --- a/src/Compiler.js +++ b/src/Compiler.js @@ -80,30 +80,30 @@ function Compiler(markup, attrMarkup, directives, widgets){  }  Compiler.prototype = { -  compile: function(element) { -    element = jqLite(element); +  compile: function(templateElement) { +    templateElement = jqLite(templateElement);      var index = 0,          template, -        parent = element.parent(); +        parent = templateElement.parent();      if (parent && parent[0]) {        parent = parent[0];        for(var i = 0; i < parent.childNodes.length; i++) { -        if (parent.childNodes[i] == element[0]) { +        if (parent.childNodes[i] == templateElement[0]) {            index = i;          }        }      } -    template = this.templatize(element, index, 0) || new Template(); -    return function(element, parentScope){ -      element = jqLite(element); -      var scope = parentScope && parentScope.$eval -          ? parentScope -          : createScope(parentScope); +    template = this.templatize(templateElement, index, 0) || new Template(); +    return function(scope, element){ +      scope = scope || createScope(); +      element = element === true +        ? templateElement.cloneNode() +        : (jqLite(element) || templateElement);        element.data($$scope, scope);        template.attach(element, scope);        scope.$element = element;        scope.$eval(); -      return scope; +      return {scope:scope, view:element};      };    }, diff --git a/src/widgets.js b/src/widgets.js index 58c22081..14d6fe10 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -676,7 +676,7 @@ angularWidget('ng:include', function(element){            xhr('GET', src, function(code, response){              element.html(response);              childScope = useScope || createScope(scope); -            compiler.compile(element)(element, childScope); +            compiler.compile(element)(childScope);              scope.$eval(onloadExp);            });          } else { @@ -793,7 +793,7 @@ var ngSwitch = angularWidget('ng:switch', function (element){            var caseElement = switchCase.element.cloneNode();            element.append(caseElement);            childScope.$tryEval(switchCase.change, element); -          switchCase.template(caseElement, childScope); +          switchCase.template(childScope, caseElement);          }        });      }); @@ -945,7 +945,7 @@ angularWidget("@ng:repeat", function(expression, element){                    (index == collectionLength - 1 ? 'last' : 'middle');              lastElement.after(cloneElement = element.cloneNode());              cloneElement.attr('ng:repeat-index', index); -            linker(cloneElement, childScope); +            linker(childScope, cloneElement);              children.push(childScope);            }            childScope.$eval(); @@ -1067,7 +1067,7 @@ angularWidget('ng:view', function(element) {          if (src) {            $xhr('GET', src, function(code, response){              element.html(response); -            compiler.compile(element)(element, childScope); +            compiler.compile(element)(childScope);            });          } else {            element.html(''); | 
