proper handlig of $element in filters

This commit is contained in:
Misko Hevery 2010-07-15 13:13:21 -07:00
parent 09e2295975
commit 9abd10e7b8
4 changed files with 63 additions and 34 deletions

View file

@ -78,6 +78,10 @@ function extend(dst) {
return dst;
}
function inherit(parent, extra) {
return extend(new (extend(function(){}, {prototype:parent}))(), extra);
};
function noop() {}
function identity($) {return $;}
function extensionMap(angular, name) {

View file

@ -26,12 +26,13 @@ angularDirective("ng:bind", function(expression){
return function(element) {
var lastValue = noop, lastError = noop;
this.$onEval(function() {
var error,
value = this.$tryEval(expression, function(e){
error = toJson(e);
}),
isHtml,
isDomElement;
var error, value, isHtml, isDomElement,
oldElement = this.hasOwnProperty('$element') ? this.$element : undefined;
this.$element = element;
value = this.$tryEval(expression, function(e){
error = toJson(e);
});
this.$element = oldElement;
if (lastValue === value && lastError == error) return;
isHtml = value instanceof HTML,
isDomElement = isElement(value);
@ -74,7 +75,9 @@ function compileBindTemplate(template){
});
});
bindTemplateCache[template] = fn = function(element){
var parts = [], self = this;
var parts = [], self = this,
oldElement = this.hasOwnProperty('$element') ? this.$element : undefined;
this.$element = element;
for ( var i = 0; i < bindings.length; i++) {
var value = bindings[i].call(self, element);
if (isElement(value))
@ -83,6 +86,7 @@ function compileBindTemplate(template){
value = toJson(value, true);
parts.push(value);
};
this.$element = oldElement;
return parts.join('');
};
}

View file

@ -83,8 +83,7 @@ function valueAccessor(scope, element) {
elementError(element, NG_VALIDATION_ERROR, null);
invalidWidgets.markValid(element);
} else {
var error,
validateScope = extend(new (extend(function(){}, {prototype:scope}))(), {$element:element});
var error, validateScope = inherit(scope, {$element:element});
error = required && !value ?
'Required' :
(value ? validator(validateScope, value) : null);

View file

@ -29,35 +29,57 @@ describe("directives", function(){
expect(scope.a).toEqual(2);
});
it('should ng:bind', function() {
var scope = compile('<div ng:bind="a"></div>');
expect(element.text()).toEqual('');
scope.a = 'misko';
scope.$eval();
expect(element.text()).toEqual('misko');
describe('ng:bind', function(){
it('should set text', function() {
var scope = compile('<div ng:bind="a"></div>');
expect(element.text()).toEqual('');
scope.a = 'misko';
scope.$eval();
expect(element.text()).toEqual('misko');
});
it('should set html', function() {
var scope = compile('<div ng:bind="html|html"></div>');
scope.html = '<div>hello</div>';
scope.$eval();
expect(lowercase(element.html())).toEqual('<div>hello</div>');
});
it('should set element element', function() {
angularFilter.myElement = function() {
return jqLite('<a>hello</a>');
};
var scope = compile('<div ng:bind="0|myElement"></div>');
scope.$eval();
expect(lowercase(element.html())).toEqual('<a>hello</a>');
});
it('should have $element set to current bind element', function(){
angularFilter.myFilter = function(){
this.$element.text('HELLO');
};
var scope = compile('<div>before<div ng:bind="0|myFilter"></div>after</div>');
expect(scope.$element.text()).toEqual("beforeHELLOafter");
});
});
it('should ng:bind html', function() {
var scope = compile('<div ng:bind="html|html"></div>');
scope.html = '<div>hello</div>';
scope.$eval();
expect(lowercase(element.html())).toEqual('<div>hello</div>');
});
describe('ng:bind-template', function(){
it('should ng:bind-template', function() {
var scope = compile('<div ng:bind-template="Hello {{name}}!"></div>');
scope.$set('name', 'Misko');
scope.$eval();
expect(element.text()).toEqual('Hello Misko!');
});
it('should ng:bind element', function() {
angularFilter.myElement = function() {
return jqLite('<a>hello</a>');
};
var scope = compile('<div ng:bind="0|myElement"></div>');
scope.$eval();
expect(lowercase(element.html())).toEqual('<a>hello</a>');
});
it('should have $element set to current bind element', function(){
angularFilter.myFilter = function(){
this.$element.text('HELLO');
};
var scope = compile('<div>before<div ng:bind-template="{{0|myFilter}}"></div>after</div>');
expect(scope.$element.text()).toEqual("beforeHELLOafter");
});
it('should ng:bind-template', function() {
var scope = compile('<div ng:bind-template="Hello {{name}}!"></div>');
scope.$set('name', 'Misko');
scope.$eval();
expect(element.text()).toEqual('Hello Misko!');
});
it('should ng:bind-attr', function(){