diff options
| author | Misko Hevery | 2011-02-13 16:13:21 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2011-02-16 08:59:57 -0500 | 
| commit | c90abf057b0370cf5beb62aa960f1df008c802ef (patch) | |
| tree | 039525ec1ee518175010693efd278fa105815285 /src | |
| parent | cdc093a463e8f8a925cbb9f2b55bedf0a1d8e7e8 (diff) | |
| download | angular.js-c90abf057b0370cf5beb62aa960f1df008c802ef.tar.bz2 | |
Changed the angular.compile(element)(scope[, cloneAttachNode])
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 20 | ||||
| -rw-r--r-- | src/Compiler.js | 15 | ||||
| -rw-r--r-- | src/jqLite.js | 9 | ||||
| -rw-r--r-- | src/widgets.js | 29 | 
4 files changed, 40 insertions, 33 deletions
| diff --git a/src/Angular.js b/src/Angular.js index 87be29a7..6e5786ec 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -803,17 +803,18 @@ function merge(src, dst) {     </pre>   *   * @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 + * @returns {function([scope][, cloneAttachFn])} 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. + *   * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the + *               `template` and call the `cloneAttachFn` allowing the caller to attach the + *               clonned elements to the DOM at the approriate place. The `cloneAttachFn` is + *               called as: <br/> `cloneAttachFn(clonedElement, scope)`: + * + *     * `clonedElement` - is a clone of the originale `element` passed into the compiler. + *     * `scope` - is the current scope with which the linking function is working with.   *   * Calling the template function returns object: `{scope:?, view:?}`, where:   * @@ -1006,7 +1007,7 @@ function toKeyValue(obj) {  function angularInit(config){    if (config.autobind) {      // TODO default to the source of angular.js -    var scope = compile(window.document)(null, createScope({'$config':config})), +    var scope = compile(window.document)(createScope({'$config':config})).scope,          $browser = scope.$service('$browser');      if (config.css) @@ -1048,8 +1049,7 @@ function bindJQuery(){    if (jQuery) {      jqLite = jQuery;      extend(jQuery.fn, { -      scope: JQLitePrototype.scope, -      cloneNode: JQLitePrototype.cloneNode +      scope: JQLitePrototype.scope      });    } else {      jqLite = jqLiteWrap; diff --git a/src/Compiler.js b/src/Compiler.js index 77c83846..78d7a2b0 100644 --- a/src/Compiler.js +++ b/src/Compiler.js @@ -93,14 +93,17 @@ Compiler.prototype = {        }      }      template = this.templatize(templateElement, index, 0) || new Template(); -    return function(scope, element){ -      scope = scope || createScope(); -      element = element === true -        ? templateElement.cloneNode() -        : (element ? jqLite(element) : templateElement); +    return function(scope, cloneConnectFn){ +      // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart +      // and sometimes changes the structure of the DOM. +      var element = cloneConnectFn +        ? JQLitePrototype.clone.call(templateElement) // IMPORTAN!!! +        : templateElement; +        scope = scope || createScope();        element.data($$scope, scope); -      template.attach(element, scope);        scope.$element = element; +      (cloneConnectFn||noop)(element, scope); +      template.attach(element, scope);        scope.$eval();        return {scope:scope, view:element};      }; diff --git a/src/jqLite.js b/src/jqLite.js index 8a507212..c4a10a0b 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -72,7 +72,7 @@ function JQLite(element) {    }  } -function JQLiteCloneNode(element) { +function JQLiteClone(element) {    return element.cloneNode(true);  } @@ -370,12 +370,15 @@ forEach({      return element.parentNode || null;    }, +  next: function(element) { +    return element.nextSibling; +  }, +    find: function(element, selector) {      return element.getElementsByTagName(selector);    }, -  clone: JQLiteCloneNode, -  cloneNode: JQLiteCloneNode +  clone: JQLiteClone  }, function(fn, name){    /**     * chaining functions diff --git a/src/widgets.js b/src/widgets.js index ce877c71..d58e7789 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -790,10 +790,10 @@ var ngSwitch = angularWidget('ng:switch', function (element){        forEach(cases, function(switchCase){          if (!found && switchCase.when(childScope, value)) {            found = true; -          var caseElement = switchCase.element.cloneNode(); -          element.append(caseElement);            childScope.$tryEval(switchCase.change, element); -          switchCase.template(childScope, caseElement); +          switchCase.template(childScope, function(caseElement){ +            element.append(caseElement); +          });          }        });      }); @@ -886,11 +886,11 @@ angularWidget('a', function() {        </doc:scenario>      </doc:example>   */ -angularWidget("@ng:repeat", function(expression, element){ +angularWidget('@ng:repeat', function(expression, element){    element.removeAttr('ng:repeat'); -  element.replaceWith(jqLite("<!-- ng:repeat: " + expression + " --!>")); +  element.replaceWith(jqLite('<!-- ng:repeat: ' + expression + ' --!>'));    var linker = this.compile(element); -  return function(reference){ +  return function(iterStartElement){      var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/),          lhs, rhs, valueIdent, keyIdent;      if (! match) { @@ -910,10 +910,9 @@ angularWidget("@ng:repeat", function(expression, element){      var children = [], currentScope = this;      this.$onEval(function(){        var index = 0, -          cloneElement,            childCount = children.length, -          lastElement = reference, -          collection = this.$tryEval(rhs, reference), +          lastIterElement = iterStartElement, +          collection = this.$tryEval(rhs, iterStartElement),            is_array = isArray(collection),            collectionLength = 0,            childScope, @@ -934,6 +933,7 @@ angularWidget("@ng:repeat", function(expression, element){              childScope = children[index];              childScope[valueIdent] = collection[key];              if (keyIdent) childScope[keyIdent] = key; +            lastIterElement = childScope.$element;            } else {              // grow children              childScope = createScope(currentScope); @@ -943,13 +943,14 @@ angularWidget("@ng:repeat", function(expression, element){              childScope.$position = index == 0                  ? 'first'                  : (index == collectionLength - 1 ? 'last' : 'middle'); -            lastElement.after(cloneElement = element.cloneNode()); -            cloneElement.attr('ng:repeat-index', index); -            linker(childScope, cloneElement);              children.push(childScope); +            linker(childScope, function(clone){ +              clone.attr('ng:repeat-index', index); +              lastIterElement.after(clone); +              lastIterElement = clone; +            });            }            childScope.$eval(); -          lastElement = childScope.$element;            index ++;          }        } @@ -957,7 +958,7 @@ angularWidget("@ng:repeat", function(expression, element){        while(children.length > index) {          children.pop().$element.remove();        } -    }, reference); +    }, iterStartElement);    };  }); | 
