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

Commit

Permalink
feat(mustache): Move unobserved mustache attributes to the flush phase
Browse files Browse the repository at this point in the history
Closes #734
  • Loading branch information
vicb authored and mhevery committed Mar 15, 2014
1 parent 1a3e56f commit 56647a3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 17 deletions.
22 changes: 19 additions & 3 deletions lib/core_dom/directive.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
part of angular.core.dom;

/**
* Callback function used to notify of attribute changes.
*/
/// Callback function used to notify of attribute changes.
typedef AttributeChanged(String newValue);

/// Callback function used to notify of observer changes.
typedef void ObserverChanged(bool hasListeners);

/**
* NodeAttrs is a facade for element attributes. The facade is responsible
* for normalizing attribute names as well as allowing access to the
Expand All @@ -15,6 +16,8 @@ class NodeAttrs {

Map<String, List<AttributeChanged>> _observers;

Map<String, List<ObserverChanged>> _observerListeners = {};

NodeAttrs(this.element);

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

notifyFn(this[attributeName]);

if (_observerListeners.containsKey(attributeName)) {
_observerListeners[attributeName].forEach((cb) => cb(true));
}
}

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

Iterable<String> get keys => element.attributes.keys;

void listenObserverChanges(String attributeName, ObserverChanged fn) {
if (_observerListeners == null) {
_observerListeners = <String, List<ObserverChanged>>{};
}
_observerListeners.putIfAbsent(attributeName, () => <ObserverChanged>[])
.add(fn);
fn(false);
}
}

/**
Expand Down
28 changes: 15 additions & 13 deletions lib/core_dom/ng_mustache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,30 @@ class NgTextMustacheDirective {
AST ast = new PureFunctionAST('[[$markup]]', new ArrayFn(), items);
scope.watch(ast, interpolation.call, readOnly: true);
}

}

// This Directive is special and does not go through injection.
@NgDirective(selector: r'[*=/{{.*}}/]')
class NgAttrMustacheDirective {
bool _hasObservers;
Watch _watch;

// This Directive is special and does not go through injection.
NgAttrMustacheDirective(NodeAttrs attrs,
String markup,
Interpolate interpolate,
Scope scope,
AstParser parser,
FilterMap filters) {

var eqPos = markup.indexOf('=');
var attrName = markup.substring(0, eqPos);
var attrValue = markup.substring(eqPos + 1);
Interpolation interpolation = interpolate(attrValue);
var lastValue = markup;
interpolation.setter = (text) {
Interpolation interpolation = interpolate(attrValue)..setter = (text) {
if (lastValue != text) lastValue = attrs[attrName] = text;
};

// TODO(misko): figure out how to remove call to setter. It slows down
// View instantiation
interpolation.setter('');
Expand All @@ -47,16 +51,14 @@ class NgAttrMustacheDirective {
.toList();

AST ast = new PureFunctionAST('[[$markup]]', new ArrayFn(), items);
/*
Attribute bindings are tricky. They need to be resolved on digest
inline with components so that any bindings to component can
be resolved before the component attach method. But once the
component is attached we need to run on the flush cycle rather
then digest cycle.
*/
// TODO(misko): figure out how to get most of these on observe rather then
// watch.
scope.watch(ast, interpolation.call);

attrs.listenObserverChanges(attrName, (hasObservers) {
if (_hasObservers != hasObservers) {
hasObservers = hasObservers;
if (_watch != null) _watch.remove();
_watch = scope.watch(ast, interpolation.call, readOnly: !hasObservers);
}
});
}
}

2 changes: 1 addition & 1 deletion test/core_dom/ng_mustache_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ main() {

}

@NgFilter(name:'hello')
@NgFilter(name: 'hello')
class _HelloFilter {
call(String str) {
return 'Hello, $str!';
Expand Down

0 comments on commit 56647a3

Please sign in to comment.