diff options
| author | Misko Hevery | 2010-12-07 11:39:59 -0800 |
|---|---|---|
| committer | Misko Hevery | 2010-12-08 14:20:26 -0800 |
| commit | fa722447f89e0215463cb39dfd1532189057fea8 (patch) | |
| tree | 6b82a971ddad19ac955650eccfcae908f29a5096 | |
| parent | 81d10e819eac778d231b6ba06521c9562d0146cf (diff) | |
| download | angular.js-fa722447f89e0215463cb39dfd1532189057fea8.tar.bz2 | |
Fixed failed assignments of form abj[0].name=value
Closes #169
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | src/parser.js | 55 | ||||
| -rw-r--r-- | test/ParserSpec.js | 8 | ||||
| -rw-r--r-- | test/testabilityPatch.js | 2 | ||||
| -rw-r--r-- | test/widgetsSpec.js | 7 |
5 files changed, 51 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index cd0d295b..56a43cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # <angular/> 0.9.7 sonic-cream (in-progress) # +### Bug Fixes +- Fixed failed assignments of form obj[0].name=value (issue #169) # <angular/> 0.9.6 night-vision (2010-12-06) # diff --git a/src/parser.js b/src/parser.js index 992696ee..621b0045 100644 --- a/src/parser.js +++ b/src/parser.js @@ -9,7 +9,7 @@ var OPERATORS = { '/':function(self, a,b){return a/b;}, '%':function(self, a,b){return a%b;}, '^':function(self, a,b){return a^b;}, - '=':function(self, a,b){return setter(self, a, b);}, + '=':noop, '==':function(self, a,b){return a==b;}, '!=':function(self, a,b){return a!=b;}, '<':function(self, a,b){return a<b;}, @@ -142,6 +142,7 @@ function lex(text, parseStringsForObjects){ function readIdent() { var ident = ""; var start = index; + var fn; while (index < text.length) { var ch = text.charAt(index); if (ch == '.' || isIdent(ch) || isNumber(ch)) { @@ -151,12 +152,17 @@ function lex(text, parseStringsForObjects){ } index++; } - var fn = OPERATORS[ident]; - if (!fn) { - fn = getterFn(ident); - fn.isAssignable = ident; - } - tokens.push({index:start, text:ident, fn:fn, json: OPERATORS[ident]}); + fn = OPERATORS[ident]; + tokens.push({ + index:start, + text:ident, + json: fn, + fn:fn||extend(getterFn(ident), { + assign:function(self, value){ + return setter(self, ident, value); + } + }) + }); } function readString(quote) { @@ -384,14 +390,17 @@ function parser(text, json){ function assignment(){ var left = logicalOR(); + var right; var token; if (token = expect('=')) { - if (!left.isAssignable) { + if (!left.assign) { throwError("implies assignment but [" + text.substring(0, token.index) + "] can not be assigned to", token); } - var ident = function(){return left.isAssignable;}; - return binaryFn(ident, token.fn, logicalOR()); + right = logicalOR(); + return function(self){ + return left.assign(self, right(self)); + }; } else { return left; } @@ -518,28 +527,28 @@ function parser(text, json){ function fieldAccess(object) { var field = expect().text; var getter = getterFn(field); - var fn = function (self){ + return extend(function (self){ return getter(object(self)); - }; - fn.isAssignable = field; - return fn; + }, { + assign:function(self, value){ + return setter(object(self), field, value); + } + }); } function objectIndex(obj) { var indexFn = expression(); consume(']'); - if (expect('=')) { - var rhs = expression(); - return function (self){ - return obj(self)[indexFn(self)] = rhs(self); - }; - } else { - return function (self){ + return extend( + function (self){ var o = obj(self); var i = indexFn(self); return (o) ? o[i] : _undefined; - }; - } + }, { + assign:function(self, value){ + return obj(self)[indexFn(self)] = value; + } + }); } function functionCall(fn) { diff --git a/test/ParserSpec.js b/test/ParserSpec.js index 06cec2b3..c26125da 100644 --- a/test/ParserSpec.js +++ b/test/ParserSpec.js @@ -413,4 +413,12 @@ describe('parser', function() { expect(scope.$eval("a=undefined")).not.toBeDefined(); expect(scope.$get("a")).not.toBeDefined(); }); + + it('should allow assignment after array dereference', function(){ + scope = angular.scope(); + scope.obj = [{}]; + scope.$eval('obj[0].name=1'); + expect(scope.obj.name).toBeUndefined(); + expect(scope.obj[0].name).toEqual(1); + }); }); diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js index ea5c8ab7..d389ae19 100644 --- a/test/testabilityPatch.js +++ b/test/testabilityPatch.js @@ -13,6 +13,8 @@ if (window.jstestdriver) { } beforeEach(function(){ + // This is to reset parsers global cache of expressions. + compileCache = {}; this.addMatchers({ toBeInvalid: function(){ var element = jqLite(this.actual); diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index ceec2c90..7253c26f 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -41,6 +41,13 @@ describe("widget", function(){ expect(scope.$get('name')).toEqual('Kai'); expect(scope.$get('count')).toEqual(2); }); + + it('should allow complex refernce binding', function(){ + compile('<div ng:init="obj={abc:{}}">'+ + '<input type="Text" name="obj[\'abc\'].name" value="Misko""/>'+ + '</div>'); + expect(scope.obj['abc'].name).toEqual('Misko'); + }); describe("ng:format", function(){ |
