Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
Allow binding to computed properties
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelw committed Nov 27, 2013
1 parent c24659f commit d72755a
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 13 deletions.
52 changes: 39 additions & 13 deletions src/polymer-expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,27 @@
}
};

function MemberExpression(object, property) {
this.object = object;
this.property = property;
}

MemberExpression.prototype = {
valueFn: function() {
var object = this.object;
var property = this.property;
return function(values) {
return object(values)[property(values)];
};
},

setValue: function(object, newValue, depsValues) {
object = this.object(depsValues);
var property = this.property(depsValues);
return object[property] = newValue;
}
};

function Filter(name, args) {
this.name = name;
this.args = args;
Expand Down Expand Up @@ -189,7 +210,7 @@
};

function getFn(arg) {
return arg instanceof IdentPath ? arg.valueFn() : arg;
return typeof arg == 'function' ? arg : arg.valueFn();
}

function ASTDelegate() {
Expand All @@ -208,7 +229,8 @@
createLabeledStatement: function(label, expression) {
this.labeledStatements.push({
label: label,
expression: expression instanceof IdentPath ? expression.valueFn() : expression
expression: typeof expression == 'function' ? expression
: expression.valueFn()
});
return expression;
},
Expand Down Expand Up @@ -253,14 +275,9 @@
},

createMemberExpression: function(accessor, object, property) {
if (accessor === '[') {
object = getFn(object);
property = getFn(property);
return function(values) {
return object(values)[property(values)];
};
}
return new IdentPath(this, property.name, object);
return accessor === '[' ?
new MemberExpression(getFn(object), getFn(property)) :
new IdentPath(this, property.name, object);
},

createLiteral: function(token) {
Expand Down Expand Up @@ -354,7 +371,16 @@

var self = this;
var setValueFn = function(newValue) {
self.setValue(model, newValue);
var values;
if (self.paths.length == 1) {
values = self.paths[0].getValueFrom(model);
} else {
values = [];
for (var i = 0; i < self.paths.length; i++)
values[i] = self.paths[i].getValueFrom(model);
}

self.setValue(model, newValue, values);
};

if (paths.length === 1) {
Expand All @@ -375,14 +401,14 @@
return binding;
},

setValue: function(model, newValue) {
setValue: function(model, newValue, depsValues) {
var count = this.filters ? this.filters.length : 0;
while (count-- > 0) {
newValue = this.filters[count].toModel(newValue);
}

if (this.expression.setValue)
return this.expression.setValue(model, newValue);
return this.expression.setValue(model, newValue, depsValues);
}
}

Expand Down
60 changes: 60 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,66 @@ suite('PolymerExpressions', function() {
assert.equal('F', div.childNodes[1].textContent);
});

test('two-way computed property', function() {
var div = createTestHtml(
'<template bind="{{ }}">' +
'<input value="{{ bar[\'contains space\'] }}">' +
'</template>');

var model = {
bar: {
'contains space': 'a'
}
};

recursivelySetTemplateModel(div, model);
Platform.performMicrotaskCheckpoint();
assert.equal('a', div.childNodes[1].value);

div.childNodes[1].value = 'b';
dispatchEvent('input', div.childNodes[1]);

Platform.performMicrotaskCheckpoint();
assert.equal('b', model.bar['contains space']);
});

test('dynamic two-way computed property', function() {
var div = createTestHtml(
'<template bind="{{ }}">' +
'<input value="{{ foo[bar] }}">' +
'</template>');

var model = {
foo: {
a: '1',
b: '3'
},
bar: 'a'
};

recursivelySetTemplateModel(div, model);
Platform.performMicrotaskCheckpoint();
assert.equal('1', div.childNodes[1].value);

div.childNodes[1].value = '2';
dispatchEvent('input', div.childNodes[1]);

Platform.performMicrotaskCheckpoint();
assert.equal('2', model.foo.a);
assert.equal('3', model.foo.b);

model.bar = 'b';
Platform.performMicrotaskCheckpoint();
assert.equal('3', div.childNodes[1].value);

div.childNodes[1].value = '4';
dispatchEvent('input', div.childNodes[1]);

Platform.performMicrotaskCheckpoint();
assert.equal('2', model.foo.a);
assert.equal('4', model.foo.b);
});

test('two-way filter', function() {
PolymerExpressions.filters.hex = hex;

Expand Down

0 comments on commit d72755a

Please sign in to comment.