Skip to content

Commit 9abd10e

Browse files
committed
proper handlig of $element in filters
1 parent 09e2295 commit 9abd10e

4 files changed

Lines changed: 63 additions & 34 deletions

File tree

src/Angular.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ function extend(dst) {
7878
return dst;
7979
}
8080

81+
function inherit(parent, extra) {
82+
return extend(new (extend(function(){}, {prototype:parent}))(), extra);
83+
};
84+
8185
function noop() {}
8286
function identity($) {return $;}
8387
function extensionMap(angular, name) {

src/directives.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ angularDirective("ng:bind", function(expression){
2626
return function(element) {
2727
var lastValue = noop, lastError = noop;
2828
this.$onEval(function() {
29-
var error,
30-
value = this.$tryEval(expression, function(e){
31-
error = toJson(e);
32-
}),
33-
isHtml,
34-
isDomElement;
29+
var error, value, isHtml, isDomElement,
30+
oldElement = this.hasOwnProperty('$element') ? this.$element : undefined;
31+
this.$element = element;
32+
value = this.$tryEval(expression, function(e){
33+
error = toJson(e);
34+
});
35+
this.$element = oldElement;
3536
if (lastValue === value && lastError == error) return;
3637
isHtml = value instanceof HTML,
3738
isDomElement = isElement(value);
@@ -74,7 +75,9 @@ function compileBindTemplate(template){
7475
});
7576
});
7677
bindTemplateCache[template] = fn = function(element){
77-
var parts = [], self = this;
78+
var parts = [], self = this,
79+
oldElement = this.hasOwnProperty('$element') ? this.$element : undefined;
80+
this.$element = element;
7881
for ( var i = 0; i < bindings.length; i++) {
7982
var value = bindings[i].call(self, element);
8083
if (isElement(value))
@@ -83,6 +86,7 @@ function compileBindTemplate(template){
8386
value = toJson(value, true);
8487
parts.push(value);
8588
};
89+
this.$element = oldElement;
8690
return parts.join('');
8791
};
8892
}

src/widgets.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ function valueAccessor(scope, element) {
8383
elementError(element, NG_VALIDATION_ERROR, null);
8484
invalidWidgets.markValid(element);
8585
} else {
86-
var error,
87-
validateScope = extend(new (extend(function(){}, {prototype:scope}))(), {$element:element});
86+
var error, validateScope = inherit(scope, {$element:element});
8887
error = required && !value ?
8988
'Required' :
9089
(value ? validator(validateScope, value) : null);

test/directivesSpec.js

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,57 @@ describe("directives", function(){
2929
expect(scope.a).toEqual(2);
3030
});
3131

32-
it('should ng:bind', function() {
33-
var scope = compile('<div ng:bind="a"></div>');
34-
expect(element.text()).toEqual('');
35-
scope.a = 'misko';
36-
scope.$eval();
37-
expect(element.text()).toEqual('misko');
38-
});
32+
describe('ng:bind', function(){
33+
it('should set text', function() {
34+
var scope = compile('<div ng:bind="a"></div>');
35+
expect(element.text()).toEqual('');
36+
scope.a = 'misko';
37+
scope.$eval();
38+
expect(element.text()).toEqual('misko');
39+
});
3940

40-
it('should ng:bind html', function() {
41-
var scope = compile('<div ng:bind="html|html"></div>');
42-
scope.html = '<div>hello</div>';
43-
scope.$eval();
44-
expect(lowercase(element.html())).toEqual('<div>hello</div>');
45-
});
41+
it('should set html', function() {
42+
var scope = compile('<div ng:bind="html|html"></div>');
43+
scope.html = '<div>hello</div>';
44+
scope.$eval();
45+
expect(lowercase(element.html())).toEqual('<div>hello</div>');
46+
});
47+
48+
it('should set element element', function() {
49+
angularFilter.myElement = function() {
50+
return jqLite('<a>hello</a>');
51+
};
52+
var scope = compile('<div ng:bind="0|myElement"></div>');
53+
scope.$eval();
54+
expect(lowercase(element.html())).toEqual('<a>hello</a>');
55+
});
56+
57+
it('should have $element set to current bind element', function(){
58+
angularFilter.myFilter = function(){
59+
this.$element.text('HELLO');
60+
};
61+
var scope = compile('<div>before<div ng:bind="0|myFilter"></div>after</div>');
62+
expect(scope.$element.text()).toEqual("beforeHELLOafter");
63+
});
4664

47-
it('should ng:bind element', function() {
48-
angularFilter.myElement = function() {
49-
return jqLite('<a>hello</a>');
50-
};
51-
var scope = compile('<div ng:bind="0|myElement"></div>');
52-
scope.$eval();
53-
expect(lowercase(element.html())).toEqual('<a>hello</a>');
5465
});
5566

56-
it('should ng:bind-template', function() {
57-
var scope = compile('<div ng:bind-template="Hello {{name}}!"></div>');
58-
scope.$set('name', 'Misko');
59-
scope.$eval();
60-
expect(element.text()).toEqual('Hello Misko!');
67+
describe('ng:bind-template', function(){
68+
it('should ng:bind-template', function() {
69+
var scope = compile('<div ng:bind-template="Hello {{name}}!"></div>');
70+
scope.$set('name', 'Misko');
71+
scope.$eval();
72+
expect(element.text()).toEqual('Hello Misko!');
73+
});
74+
75+
it('should have $element set to current bind element', function(){
76+
angularFilter.myFilter = function(){
77+
this.$element.text('HELLO');
78+
};
79+
var scope = compile('<div>before<div ng:bind-template="{{0|myFilter}}"></div>after</div>');
80+
expect(scope.$element.text()).toEqual("beforeHELLOafter");
81+
});
82+
6183
});
6284

6385
it('should ng:bind-attr', function(){

0 commit comments

Comments
 (0)