OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of template_binding; | 5 part of template_binding; |
6 | 6 |
7 /** Extensions to the [Node] API. */ | 7 /** Extensions to the [Node] API. */ |
8 class NodeBindExtension { | 8 class NodeBindExtension { |
9 final Node _node; | 9 final Node _node; |
10 Map<String, NodeBinding> _bindings; | 10 Map<String, Bindable> _bindings; |
11 | 11 |
12 NodeBindExtension._(this._node); | 12 NodeBindExtension._(this._node); |
13 | 13 |
14 /** | 14 /** |
15 * Binds the attribute [name] to the [path] of the [model]. | 15 * Binds the attribute [name] to the [path] of the [model]. |
16 * Path is a String of accessors such as `foo.bar.baz`. | 16 * Path is a String of accessors such as `foo.bar.baz`. |
17 * Returns the `NodeBinding` instance. | 17 * Returns the `Bindable` instance. |
18 */ | 18 */ |
19 NodeBinding bind(String name, model, [String path]) { | 19 Bindable bind(String name, value, {bool oneTime: false}) { |
| 20 // TODO(jmesserly): in Dart we could deliver an async error, which would |
| 21 // have a similar affect but be reported as a test failure. Should we? |
20 window.console.error('Unhandled binding to Node: ' | 22 window.console.error('Unhandled binding to Node: ' |
21 '$this $name $model $path'); | 23 '$this $name $value $oneTime'); |
| 24 return null; |
22 } | 25 } |
23 | 26 |
24 /** Unbinds the attribute [name]. */ | 27 /** Unbinds the attribute [name]. */ |
25 void unbind(String name) { | 28 void unbind(String name) { |
26 if (_bindings == null) return; | 29 if (_bindings == null) return; |
27 var binding = bindings.remove(name); | 30 var binding = bindings.remove(name); |
28 if (binding != null) binding.close(); | 31 if (binding != null) binding.close(); |
29 } | 32 } |
30 | 33 |
31 /** Unbinds all bound attributes. */ | 34 /** Unbinds all bound attributes. */ |
32 void unbindAll() { | 35 void unbindAll() { |
33 if (_bindings == null) return; | 36 if (_bindings == null) return; |
34 for (var binding in bindings.values.toList()) { | 37 for (var binding in bindings.values.toList()) { |
35 if (binding != null) binding.close(); | 38 if (binding != null) binding.close(); |
36 } | 39 } |
37 _bindings = null; | 40 _bindings = null; |
38 } | 41 } |
39 | 42 |
40 // TODO(jmesserly): we should return a read-only wrapper here. | 43 // TODO(jmesserly): we should return a read-only wrapper here. |
41 /** Gets the data bindings that are associated with this node. */ | 44 /** Gets the data bindings that are associated with this node. */ |
42 Map<String, NodeBinding> get bindings { | 45 Map<String, Bindable> get bindings { |
43 if (_bindings == null) _bindings = new LinkedHashMap<String, NodeBinding>(); | 46 if (_bindings == null) _bindings = new LinkedHashMap<String, Bindable>(); |
44 return _bindings; | 47 return _bindings; |
45 } | 48 } |
46 | 49 |
47 /** | 50 /** |
48 * Dispatch support so custom HtmlElement's can override these methods. | 51 * Dispatch support so custom HtmlElement's can override these methods. |
49 * A public method like [this.bind] should not call another public method such | 52 * A public method like [this.bind] should not call another public method such |
50 * as [this.unbind]. Instead it should dispatch through [_self.unbind]. | 53 * as [this.unbind]. Instead it should dispatch through [_self.unbind]. |
51 */ | 54 */ |
52 NodeBindExtension get _self => _node is NodeBindExtension ? _node : this; | 55 NodeBindExtension get _self => _node is NodeBindExtension ? _node : this; |
53 | 56 |
54 TemplateInstance _templateInstance; | 57 TemplateInstance _templateInstance; |
55 | 58 |
56 /** Gets the template instance that instantiated this node, if any. */ | 59 /** Gets the template instance that instantiated this node, if any. */ |
57 TemplateInstance get templateInstance => | 60 TemplateInstance get templateInstance => |
58 _templateInstance != null ? _templateInstance : | 61 _templateInstance != null ? _templateInstance : |
59 (_node.parent != null ? nodeBind(_node.parent).templateInstance : null); | 62 (_node.parent != null ? nodeBind(_node.parent).templateInstance : null); |
| 63 |
| 64 _open(Bindable bindable, callback(value)) => |
| 65 callback(bindable.open(callback)); |
60 } | 66 } |
61 | 67 |
62 | 68 |
63 /** Information about the instantiated template. */ | 69 /** Information about the instantiated template. */ |
64 class TemplateInstance { | 70 class TemplateInstance { |
65 // TODO(rafaelw): firstNode & lastNode should be read-synchronous | 71 // TODO(rafaelw): firstNode & lastNode should be read-synchronous |
66 // in cases where script has modified the template instance boundary. | 72 // in cases where script has modified the template instance boundary. |
67 | 73 |
68 /** The first node of this template instantiation. */ | 74 /** The first node of this template instantiation. */ |
69 final Node firstNode; | 75 Node get firstNode => _firstNode; |
70 | 76 |
71 /** | 77 /** |
72 * The last node of this template instantiation. | 78 * The last node of this template instantiation. |
73 * This could be identical to [firstNode] if the template only expanded to a | 79 * This could be identical to [firstNode] if the template only expanded to a |
74 * single node. | 80 * single node. |
75 */ | 81 */ |
76 final Node lastNode; | 82 Node get lastNode => _lastNode; |
77 | 83 |
78 /** The model used to instantiate the template. */ | 84 /** The model used to instantiate the template. */ |
79 final model; | 85 final model; |
80 | 86 |
81 TemplateInstance(this.firstNode, this.lastNode, this.model); | 87 Node _firstNode, _lastNode; |
| 88 |
| 89 TemplateInstance(this.model); |
82 } | 90 } |
OLD | NEW |