mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
Changed the angular.compile(element)(scope[, cloneAttachNode])
This commit is contained in:
parent
cdc093a463
commit
c90abf057b
10 changed files with 57 additions and 44 deletions
|
|
@ -12,7 +12,7 @@
|
|||
recommended way to deal with initializing scope is to put it in the root constructor controller.
|
||||
To migrate simply remove the call to $init() and move any code you had before $init() to the
|
||||
root controller.
|
||||
- Change API angular.compile(..) to angular.compile(element)([scope], [element/true])
|
||||
- Change API angular.compile(..) to angular.compile(element)([scope], [cloneAttachFn])
|
||||
|
||||
|
||||
<a name="0.9.11"><a/>
|
||||
|
|
|
|||
|
|
@ -44,10 +44,6 @@ raw DOM references.
|
|||
version:
|
||||
|
||||
- `scope()` - retrieves the current angular scope of the element.
|
||||
- `cloneNode()` - Clones the current node, ensuring identical structure. This is important since
|
||||
the `clone()` method implemented by jQuery under some circumstances changes the DOM
|
||||
structure, which then prevents proper application of compiled template to the cloned node.
|
||||
__Always use `cloneNode()` when cloning previously compiled templates.__
|
||||
|
||||
@param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
|
||||
@returns {Object} jQuery object.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -369,8 +369,10 @@ describe('angular', function(){
|
|||
var scope = angular.scope();
|
||||
var template = jqLite('<div>{{greeting = "hello world"}}</div>');
|
||||
var templateFn = angular.compile(template);
|
||||
var templateClone = template.cloneNode();
|
||||
mvc = templateFn(scope, templateClone);
|
||||
var templateClone = template.clone();
|
||||
mvc = templateFn(scope, function(clone){
|
||||
templateClone = clone;
|
||||
});
|
||||
expect(template.text()).toEqual('');
|
||||
expect(mvc.view.text()).toEqual('hello world');
|
||||
expect(mvc.view).toEqual(templateClone);
|
||||
|
|
@ -380,7 +382,7 @@ describe('angular', function(){
|
|||
it('should link to cloned node and create scope', function(){
|
||||
var scope = angular.scope();
|
||||
var template = jqLite('<div>{{greeting = "hello world"}}</div>');
|
||||
mvc = angular.compile(template)(scope, true);
|
||||
mvc = angular.compile(template)(scope, noop);
|
||||
expect(template.text()).toEqual('');
|
||||
expect(mvc.view.text()).toEqual('hello world');
|
||||
expect(mvc.scope.greeting).toEqual('hello world');
|
||||
|
|
|
|||
|
|
@ -417,7 +417,7 @@ describe('Binder', function(){
|
|||
});
|
||||
|
||||
it('BindClassEvenOdd', function(){
|
||||
var x = this.compile('<div><div ng:repeat="i in [0,1]" ng:class-even="\'e\'" ng:class-odd="\'o\'"/></div>');
|
||||
var x = this.compile('<div><div ng:repeat="i in [0,1]" ng:class-even="\'e\'" ng:class-odd="\'o\'"></div></div>');
|
||||
x.scope.$eval();
|
||||
var d1 = jqLite(x.view[0].childNodes[1]);
|
||||
var d2 = jqLite(x.view[0].childNodes[2]);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ describe('compiler', function(){
|
|||
};
|
||||
var template = compiler.compile(e);
|
||||
expect(log).toEqual("found");
|
||||
scope = template(angular.scope(), e).scope;
|
||||
scope = template(angular.scope()).scope;
|
||||
expect(e.hasClass('ng-directive')).toEqual(true);
|
||||
expect(log).toEqual("found:init");
|
||||
});
|
||||
|
|
@ -84,7 +84,7 @@ describe('compiler', function(){
|
|||
var template = this.compile(element);
|
||||
return function(marker) {
|
||||
this.$onEval(function() {
|
||||
marker.after(template(angular.scope(), true).view);
|
||||
marker.after(template(angular.scope(), noop).view);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -300,6 +300,14 @@ describe('jqLite', function(){
|
|||
expect(element.parent().length).toEqual(0);
|
||||
});
|
||||
});
|
||||
describe('next', function(){
|
||||
it('should return next sibling', function(){
|
||||
var element = jqLite('<div><b>b</b><i>i</i></div>');
|
||||
var b = element.find('b');
|
||||
var i = element.find('i');
|
||||
expect(b.next()).toJqEqual([i]);
|
||||
});
|
||||
});
|
||||
describe('find', function(){
|
||||
it('should find child by name', function(){
|
||||
var root = jqLite('<div><div>text</div></div>');
|
||||
|
|
|
|||
Loading…
Reference in a new issue