aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2010-07-15 13:13:21 -0700
committerMisko Hevery2010-07-15 13:13:21 -0700
commit9abd10e7b8a34b9dcd1a6af5ff37f57bd27cf920 (patch)
tree1dac2305341b58cb595ebc4b71ea5debf121e37b
parent09e2295975b5bb8dfc067303fee86a9f2ebb433d (diff)
downloadangular.js-9abd10e7b8a34b9dcd1a6af5ff37f57bd27cf920.tar.bz2
proper handlig of $element in filters
-rw-r--r--src/Angular.js4
-rw-r--r--src/directives.js18
-rw-r--r--src/widgets.js3
-rw-r--r--test/directivesSpec.js72
4 files changed, 63 insertions, 34 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 2b26c88d..07e9096b 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -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) {
diff --git a/src/directives.js b/src/directives.js
index bcc427e8..b57e5ecd 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -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('');
};
}
diff --git a/src/widgets.js b/src/widgets.js
index 0b77dbf4..7bd51c8c 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -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);
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index a42faa9a..b6ccf764 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -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 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>');
- });
+ 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 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 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!');
+ 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 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-attr', function(){