refactor(directives): directives use declare that they listen to onChange in the annotations

This commit is contained in:
vsavkin
2015-02-06 13:19:47 -08:00
parent ee3f709fbf
commit 9240b09011
7 changed files with 91 additions and 27 deletions

View File

@ -1,5 +1,5 @@
import {ABSTRACT, CONST, normalizeBlank} from 'angular2/src/facade/lang';
import {List} from 'angular2/src/facade/collection';
import {ABSTRACT, CONST, normalizeBlank, isPresent} from 'angular2/src/facade/lang';
import {ListWrapper, List} from 'angular2/src/facade/collection';
import {TemplateConfig} from './template_config';
@ABSTRACT()
@ -30,6 +30,10 @@ export class Directive {
this.bind = bind;
this.lifecycle = lifecycle;
}
hasLifecycleHook(hook:string):boolean {
return isPresent(this.lifecycle) ? ListWrapper.contains(this.lifecycle, hook) : false;
}
}
export class Component extends Directive {
@ -133,4 +137,5 @@ export class Template extends Directive {
}
}
export var onDestroy = "onDestroy";
export const onDestroy = "onDestroy";
export const onChange = "onChange";

View File

@ -4,12 +4,11 @@ import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
import {Injector, Key, Dependency, bind, Binding, NoProviderError, ProviderError, CyclicDependencyError} from 'angular2/di';
import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
import {EventEmitter} from 'angular2/src/core/annotations/events';
import {onDestroy} from 'angular2/src/core/annotations/annotations';
import {View, ProtoView} from 'angular2/src/core/compiler/view';
import {LightDom, SourceLightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {NgElement} from 'angular2/src/core/dom/element';
import {Directive} from 'angular2/src/core/annotations/annotations'
import {Directive, onChange, onDestroy} from 'angular2/src/core/annotations/annotations'
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config'
var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
@ -123,18 +122,19 @@ export class DirectiveDependency extends Dependency {
export class DirectiveBinding extends Binding {
callOnDestroy:boolean;
callOnChange:boolean;
onCheck:boolean;
constructor(key:Key, factory:Function, dependencies:List, providedAsPromise:boolean, callOnDestroy:boolean) {
constructor(key:Key, factory:Function, dependencies:List, providedAsPromise:boolean, annotation:Directive) {
super(key, factory, dependencies, providedAsPromise);
this.callOnDestroy = callOnDestroy;
this.callOnDestroy = isPresent(annotation) && annotation.hasLifecycleHook(onDestroy);
this.callOnChange = isPresent(annotation) && annotation.hasLifecycleHook(onChange);
//this.onCheck = isPresent(annotation) && annotation.hasLifecycleHook(onCheck);
}
static createFromBinding(b:Binding, annotation:Directive):Binding {
var deps = ListWrapper.map(b.dependencies, DirectiveDependency.createFrom);
var callOnDestroy = isPresent(annotation) && isPresent(annotation.lifecycle) ?
ListWrapper.contains(annotation.lifecycle, onDestroy) :
false;
return new DirectiveBinding(b.key, b.factory, deps, b.providedAsPromise, callOnDestroy);
return new DirectiveBinding(b.key, b.factory, deps, b.providedAsPromise, annotation);
}
static createFromType(type:Type, annotation:Directive):Binding {
@ -567,7 +567,7 @@ export class ElementInjector extends TreeNode {
return _undefined;
}
getAtIndex(index:int) {
getDirectiveAtIndex(index:int) {
if (index == 0) return this._obj0;
if (index == 1) return this._obj1;
if (index == 2) return this._obj2;
@ -581,6 +581,21 @@ export class ElementInjector extends TreeNode {
throw new OutOfBoundsAccess(index);
}
getDirectiveBindingAtIndex(index:int) {
var p = this._proto;
if (index == 0) return p._binding0;
if (index == 1) return p._binding1;
if (index == 2) return p._binding2;
if (index == 3) return p._binding3;
if (index == 4) return p._binding4;
if (index == 5) return p._binding5;
if (index == 6) return p._binding6;
if (index == 7) return p._binding7;
if (index == 8) return p._binding8;
if (index == 9) return p._binding9;
throw new OutOfBoundsAccess(index);
}
hasInstances() {
return this._constructionCounter > 0;
}

View File

@ -12,7 +12,6 @@ import {FIELD, IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular
import {Injector} from 'angular2/di';
import {NgElement} from 'angular2/src/core/dom/element';
import {ViewPort} from './viewport';
import {OnChange} from './interfaces';
import {Content} from './shadow_dom_emulation/content_tag';
import {LightDom, DestinationLightDom} from './shadow_dom_emulation/light_dom';
import {ShadowDomStrategy} from './shadow_dom_strategy';
@ -211,7 +210,9 @@ export class View {
_notifyDirectiveAboutChanges(groupMemento, records:List) {
var dir = groupMemento.directive(this.elementInjectors);
if (dir instanceof OnChange) {
var binding = groupMemento.directiveBinding(this.elementInjectors);
if (binding.callOnChange) {
dir.onChange(this._collectChanges(records));
}
}
@ -552,7 +553,7 @@ export class DirectivePropertyMemento {
invoke(record:ChangeRecord, elementInjectors:List<ElementInjector>) {
var elementInjector:ElementInjector = elementInjectors[this._elementInjectorIndex];
var directive = elementInjector.getAtIndex(this._directiveIndex);
var directive = elementInjector.getDirectiveAtIndex(this._directiveIndex);
this._setter(directive, record.currentValue);
}
}
@ -581,7 +582,12 @@ class DirectivePropertyGroupMemento {
directive(elementInjectors:List<ElementInjector>) {
var elementInjector:ElementInjector = elementInjectors[this._elementInjectorIndex];
return elementInjector.getAtIndex(this._directiveIndex);
return elementInjector.getDirectiveAtIndex(this._directiveIndex);
}
directiveBinding(elementInjectors:List<ElementInjector>) {
var elementInjector:ElementInjector = elementInjectors[this._elementInjectorIndex];
return elementInjector.getDirectiveBindingAtIndex(this._directiveIndex);
}
}

View File

@ -1,4 +1,4 @@
import {Template} from 'angular2/src/core/annotations/annotations';
import {Template, onChange} from 'angular2/src/core/annotations/annotations';
import {OnChange} from 'angular2/src/core/compiler/interfaces';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {View} from 'angular2/src/core/compiler/view';
@ -7,6 +7,7 @@ import {ListWrapper} from 'angular2/src/facade/collection';
@Template({
selector: '[foreach][in]',
lifecycle: [onChange],
bind: {
'in': 'iterable[]'
}