Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 56647a3

Browse files
vicbmhevery
authored andcommitted
feat(mustache): Move unobserved mustache attributes to the flush phase
Closes #734
1 parent 1a3e56f commit 56647a3

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

lib/core_dom/directive.dart

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
part of angular.core.dom;
22

3-
/**
4-
* Callback function used to notify of attribute changes.
5-
*/
3+
/// Callback function used to notify of attribute changes.
64
typedef AttributeChanged(String newValue);
75

6+
/// Callback function used to notify of observer changes.
7+
typedef void ObserverChanged(bool hasListeners);
8+
89
/**
910
* NodeAttrs is a facade for element attributes. The facade is responsible
1011
* for normalizing attribute names as well as allowing access to the
@@ -15,6 +16,8 @@ class NodeAttrs {
1516

1617
Map<String, List<AttributeChanged>> _observers;
1718

19+
Map<String, List<ObserverChanged>> _observerListeners = {};
20+
1821
NodeAttrs(this.element);
1922

2023
operator [](String attributeName) => element.attributes[attributeName];
@@ -41,6 +44,10 @@ class NodeAttrs {
4144
.add(notifyFn);
4245

4346
notifyFn(this[attributeName]);
47+
48+
if (_observerListeners.containsKey(attributeName)) {
49+
_observerListeners[attributeName].forEach((cb) => cb(true));
50+
}
4451
}
4552

4653
void forEach(void f(String k, String v)) {
@@ -51,6 +58,15 @@ class NodeAttrs {
5158
element.attributes.containsKey(attributeName);
5259

5360
Iterable<String> get keys => element.attributes.keys;
61+
62+
void listenObserverChanges(String attributeName, ObserverChanged fn) {
63+
if (_observerListeners == null) {
64+
_observerListeners = <String, List<ObserverChanged>>{};
65+
}
66+
_observerListeners.putIfAbsent(attributeName, () => <ObserverChanged>[])
67+
.add(fn);
68+
fn(false);
69+
}
5470
}
5571

5672
/**

lib/core_dom/ng_mustache.dart

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,30 @@ class NgTextMustacheDirective {
1818
AST ast = new PureFunctionAST('[[$markup]]', new ArrayFn(), items);
1919
scope.watch(ast, interpolation.call, readOnly: true);
2020
}
21-
2221
}
2322

2423
// This Directive is special and does not go through injection.
2524
@NgDirective(selector: r'[*=/{{.*}}/]')
2625
class NgAttrMustacheDirective {
26+
bool _hasObservers;
27+
Watch _watch;
28+
29+
// This Directive is special and does not go through injection.
2730
NgAttrMustacheDirective(NodeAttrs attrs,
2831
String markup,
2932
Interpolate interpolate,
3033
Scope scope,
3134
AstParser parser,
3235
FilterMap filters) {
36+
3337
var eqPos = markup.indexOf('=');
3438
var attrName = markup.substring(0, eqPos);
3539
var attrValue = markup.substring(eqPos + 1);
36-
Interpolation interpolation = interpolate(attrValue);
3740
var lastValue = markup;
38-
interpolation.setter = (text) {
41+
Interpolation interpolation = interpolate(attrValue)..setter = (text) {
3942
if (lastValue != text) lastValue = attrs[attrName] = text;
4043
};
44+
4145
// TODO(misko): figure out how to remove call to setter. It slows down
4246
// View instantiation
4347
interpolation.setter('');
@@ -47,16 +51,14 @@ class NgAttrMustacheDirective {
4751
.toList();
4852

4953
AST ast = new PureFunctionAST('[[$markup]]', new ArrayFn(), items);
50-
/*
51-
Attribute bindings are tricky. They need to be resolved on digest
52-
inline with components so that any bindings to component can
53-
be resolved before the component attach method. But once the
54-
component is attached we need to run on the flush cycle rather
55-
then digest cycle.
56-
*/
57-
// TODO(misko): figure out how to get most of these on observe rather then
58-
// watch.
59-
scope.watch(ast, interpolation.call);
54+
55+
attrs.listenObserverChanges(attrName, (hasObservers) {
56+
if (_hasObservers != hasObservers) {
57+
hasObservers = hasObservers;
58+
if (_watch != null) _watch.remove();
59+
_watch = scope.watch(ast, interpolation.call, readOnly: !hasObservers);
60+
}
61+
});
6062
}
6163
}
6264

test/core_dom/ng_mustache_spec.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ main() {
110110

111111
}
112112

113-
@NgFilter(name:'hello')
113+
@NgFilter(name: 'hello')
114114
class _HelloFilter {
115115
call(String str) {
116116
return 'Hello, $str!';

0 commit comments

Comments
 (0)