aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/parser.js55
-rw-r--r--test/ParserSpec.js8
-rw-r--r--test/testabilityPatch.js2
-rw-r--r--test/widgetsSpec.js7
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(){