Chromium Code Reviews| Index: pkg/polymer/lib/auto_binding.dart |
| diff --git a/pkg/polymer/lib/auto_binding.dart b/pkg/polymer/lib/auto_binding.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..314da790897521e6e275b97491060ae4ab88d3b6 |
| --- /dev/null |
| +++ b/pkg/polymer/lib/auto_binding.dart |
| @@ -0,0 +1,117 @@ |
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +library polymer.auto_binding; |
| + |
| +import 'dart:html'; |
| +import 'package:polymer/polymer.dart'; |
| +import 'package:template_binding/template_binding.dart'; |
| + |
| +/** |
| + * The `d-auto-binding` element extends the template element. It provides a |
| + * quick and easy way to do data binding without the need to setup a model. |
|
Siggi Cherem (dart-lang)
2014/06/03 02:23:44
what does it mean "without the need to setup a mod
Jennifer Messerly
2014/06/04 04:42:17
good catch. it's their comment, but i'll try to cl
|
| + * The `d-auto-binding` element itself serves as the model and controller for |
| + * the elements it contains. Both data and event handlers can be bound. |
| + * |
| + * The `d-auto-binding` element acts just like a template that is bound to |
| + * a model. It stamps its content in the dom adjacent to itself. When the |
| + * content is stamped, the `template-bound` event is fired. |
| + * |
| + * Example: |
| + * |
| + * <template is="d-auto-binding"> |
| + * <div>Say something: <input value="{{value}}"></div> |
| + * <div>You said: {{value}}</div> |
| + * <button on-tap="{{buttonTap}}">Tap me!</button> |
| + * </template> |
| + * <script type="application/dart"> |
| + * import 'dart:html'; |
| + * import 'package:polymer/polymer.dart'; |
| + * |
| + * main() { |
| + * var template = document.querySelector('template'); |
| + * template.model = new MyModel(); |
|
Siggi Cherem (dart-lang)
2014/06/03 02:23:44
... in particular, this line seems to contradict t
Jennifer Messerly
2014/06/04 04:42:17
Done.
|
| + * } |
| + * |
| + * class MyModel { |
| + * String value = 'something'; |
| + * buttonTap() => console.log('tap!'); |
| + * } |
| + * </script> |
| + * |
| + */ |
| +// Dart note: renamed to d-auto-binding to avoid conflict with JS auto-binding. |
| +class AutoBindingElement extends TemplateElement with Polymer, Observable |
| + implements TemplateBindExtension { |
| + |
| + /// Make template_binding "extension methods" friendly. |
| + /// Note that [NodeBindExtension] is already implemented by [Polymer]. |
| + TemplateBindExtension _self; |
| + |
| + get model => _self.model; |
| + set model(value) { _self.model = value; } |
| + |
| + BindingDelegate get bindingDelegate => _self.bindingDelegate; |
| + set bindingDelegate(BindingDelegate value) { _self.bindingDelegate = value; } |
| + |
| + void clear() => _self.clear(); |
| + |
| + @override |
| + BindingDelegate get syntax => bindingDelegate; |
| + |
| + AutoBindingElement.created() : super.created() { |
| + polymerCreated(); |
| + |
| + _self = templateBindFallback(this); |
| + |
| + bindingDelegate = makeSyntax(); |
| + |
| + // delay stamping until polymer-ready so that auto-binding is not |
| + // required to load last. |
| + Polymer.onReady.then((_) { |
| + attributes['bind'] = ''; |
| + // we don't bother with an explicit signal here, we could ust a MO |
| + // if necessary |
| + async((_) { |
| + // note: this will marshall *all* the elements in the parentNode |
| + // rather than just stamped ones. We'd need to use createInstance |
| + // to fix this or something else fancier. |
| + marshalNodeReferences(parentNode); |
| + // template stamping is asynchronous so stamping isn't complete |
| + // by polymer-ready; fire an event so users can use stamped elements |
| + fire('template-bound'); |
| + }); |
| + }); |
| + } |
| + |
| + PolymerExpressions makeSyntax() => new _AutoBindingSyntax(this); |
| + |
| + DocumentFragment createInstance([model, BindingDelegate delegate]) => |
| + _self.createInstance(model, delegate); |
| +} |
| + |
| +// Dart note: this is implemented a little differently to keep it in classic |
| +// OOP style. Instead of monkeypatching findController, we override |
| +// getEventHandler to do the right thing. |
| +class _AutoBindingSyntax extends PolymerExpressions { |
| + final AutoBindingElement _node; |
| + |
| + _AutoBindingSyntax(this._node) : super(); |
| + |
| + EventListener getEventHandler(controller, target, String method) => (e) { |
| + if (controller == null || controller is! Polymer) controller = _node; |
| + |
| + if (controller is Polymer) { |
| + var args = [e, e.detail, e.currentTarget]; |
| + |
| + // Dart note: make sure we dispatch to the model, not the |
| + // AutoBindingElement instance. |
| + var obj = controller == _node ? _node.model : controller; |
| + controller.dispatchMethod(obj, method, args); |
| + } else { |
| + throw new StateError('controller $controller is not a ' |
| + 'Dart polymer-element.'); |
| + } |
| + }; |
| +} |