feat(change_detection): added support for ObservableList from package:observe

This commit is contained in:
vsavkin
2015-07-15 13:26:02 -07:00
parent 583c5ffcb5
commit d449ea5ca4
8 changed files with 244 additions and 1 deletions
@@ -603,6 +603,8 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
if (isPresent(dirDep.queryDecorator)) return this._findQuery(dirDep.queryDecorator).list;
if (dirDep.key.id === StaticKeys.instance().changeDetectorRefId) {
// We provide the component's view change detector to components and
// the surrounding component's change detector to directives.
if (dirBin.metadata.type === DirectiveMetadata.COMPONENT_TYPE) {
var componentView = this._preBuiltObjects.view.componentChildViews[this._proto.index];
return componentView.changeDetector.ref;
@@ -0,0 +1,66 @@
library angular2.directives.observable_list_iterable_diff;
import 'package:observe/observe.dart' show ObservableList;
import 'package:angular2/change_detection.dart';
import 'package:angular2/src/change_detection/pipes/iterable_changes.dart';
import 'dart:async';
class ObservableListDiff extends IterableChanges {
ChangeDetectorRef _ref;
ObservableListDiff(this._ref);
bool _updated = true;
ObservableList _collection;
StreamSubscription _subscription;
bool supports(obj) {
if (obj is ObservableList) return true;
throw "Cannot change the type of a collection";
}
onDestroy() {
if (this._subscription != null) {
this._subscription.cancel();
this._subscription = null;
this._collection = null;
}
}
dynamic transform(ObservableList collection, [List args]) {
// A new collection instance is passed in.
// - We need to set up a listener.
// - We need to transform collection.
if (!identical(_collection, collection)) {
_collection = collection;
if (_subscription != null) _subscription.cancel();
_subscription = collection.changes.listen((_) {
_updated = true;
_ref.requestCheck();
});
_updated = false;
return super.transform(collection, args);
// An update has been registered since the last change detection check.
// - We reset the flag.
// - We diff the collection.
} else if (_updated){
_updated = false;
return super.transform(collection, args);
// No updates has been registered.
// Returning this tells change detection that object has not change,
// so it should NOT update the binding.
} else {
return this;
}
}
}
class ObservableListDiffFactory implements PipeFactory {
const ObservableListDiffFactory();
bool supports(obj) => obj is ObservableList;
Pipe create(ChangeDetectorRef cdRef) {
return new ObservableListDiff(cdRef);
}
}
+5
View File
@@ -27,4 +27,9 @@ class SpyPipeFactory extends SpyObject implements PipeFactory {
@proxy
class SpyDependencyProvider extends SpyObject implements DependencyProvider {
noSuchMethod(m) => super.noSuchMethod(m);
}
@proxy
class SpyChangeDetectorRef extends SpyObject implements ChangeDetectorRef {
noSuchMethod(m) => super.noSuchMethod(m);
}
@@ -56,6 +56,7 @@ import {
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES
} from 'angular2/src/render/dom/dom_renderer';
import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
import {Log} from './utils';
/**
* Returns the root injector bindings.
@@ -107,6 +108,7 @@ function _getAppBindings() {
CompilerCache,
bind(ViewResolver).toClass(MockViewResolver),
bind(Pipes).toValue(defaultPipes),
Log,
bind(ChangeDetection).toClass(DynamicChangeDetection),
ViewLoader,
DynamicComponentLoader,