diff --git a/example/web/paper.html b/example/web/paper.html index 3e2ea0de4..167b712fb 100644 --- a/example/web/paper.html +++ b/example/web/paper.html @@ -12,15 +12,18 @@ href="bower_components/paper-progress/paper-progress.html"> +

Polymer components inside a AngularDart app

-

paper-progress

+

Property binding: paper-progress

This is a simple component that doesn't generate events; the only things that is required is property binding

The max ({{max}}) and value ({{curValue}}) properties are bound through bind-* semantics

@@ -37,7 +40,7 @@

paper-progress

-

paper-checkbox

+

Events: paper-checkbox

The checkbox will generate an event every time the value is changed

AngularDart can listen to these events through the on-* syntax

@@ -45,5 +48,12 @@

paper-checkbox

Every the value changes, the curValue ({{curValue}}) scope variable will update

+ +

Two-way binding: paper-slider

+

The slide is bound to the curValue scope variable ({{curValue}})

+ +
+ +
diff --git a/lib/core_dom/element_binder.dart b/lib/core_dom/element_binder.dart index 737b635fa..814bd9148 100644 --- a/lib/core_dom/element_binder.dart +++ b/lib/core_dom/element_binder.dart @@ -284,13 +284,26 @@ class ElementBinder { _link(nodeInjector, scope, nodeAttrs); var jsNode; - bindAttrs.forEach((String prop, ast) { + List bindAssignableProps = []; + bindAttrs.forEach((String prop, AST ast) { if (jsNode == null) jsNode = new js.JsObject.fromBrowserObject(node); scope.watchAST(ast, (v, _) { jsNode[prop] = v; }); + + if (ast.parsedExp.isAssignable) { + bindAssignableProps.add([prop, ast.parsedExp]); + } }); + if (bindAssignableProps.isNotEmpty) { + node.addEventListener('change', (_) { + bindAssignableProps.forEach((propAndExp) { + propAndExp[1].assign(scope.context, jsNode[propAndExp[0]]); + }); + }); + } + if (onEvents.isNotEmpty) { onEvents.forEach((event, value) { view.registerEvent(EventHandler.attrNameToEventName(event)); diff --git a/test/core_dom/web_components_spec.dart b/test/core_dom/web_components_spec.dart index e20fbaa46..e7a63c934 100644 --- a/test/core_dom/web_components_spec.dart +++ b/test/core_dom/web_components_spec.dart @@ -14,11 +14,24 @@ main() { describe('WebComponent support', () { TestBed _; - customProp(String prop, [elt]) { + /** + * Returns the property [prop] as read through the JS interface. + * [elt] is optional and defaults to the [TestBed]'s rootElement. + */ + customProp(String prop, [Element elt]) { if (elt == null) elt = _.rootElement; return (new js.JsObject.fromBrowserObject(elt))[prop]; } + /** + * Sets the property [prop] to [value] through the JS interface. + * [elt] is optional and defaults to the [TestBed]'s rootElement. + */ + void setCustomProp(String prop, value, [Element elt]) { + if (elt == null) elt = _.rootElement; + (new js.JsObject.fromBrowserObject(_.rootElement))[prop] = value; + } + beforeEach((TestBed tb) { _ = tb; }); @@ -58,5 +71,15 @@ main() { expect(customProp('ng-bind')).toEqual("hello"); expect(_.rootElement).toHaveText('hello'); }); + + it('should support two-way bindings for components that trigger a change event', () { + registerElement('tests-twoway', {}); + _.compile(''); + + setCustomProp('prop', 6); + _.rootElement.dispatchEvent(new Event.eventType('CustomEvent', 'change')); + + expect(_.rootScope.context['x']).toEqual(6); + }); }); }