diff options
| -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(){ | 
