refactor(change_detection): introduce enum ChangeDetectionStrategy
BREAKING CHANGE Closes #2497 - change detection strategy type changes from string to ChangeDetectionStrategy - CHECK_ONCE => ChangeDetectionStrategy.CheckOnce - CHECKED => ChangeDetectionStrategy.Checked - CHECK_ALWAYS => ChangeDetectionStrategy.CheckAlways - DETACHED => ChangeDetectionStrategy.Detached - ON_PUSH => ChangeDetectionStrategy.OnPush - DEFAULT => ChangeDetectionStrategy.Default - ON_PUSH_OBSERVE => ChangeDetectionStrategy.OnPushObserve
This commit is contained in:
@ -5,12 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export {
|
export {
|
||||||
CHECK_ONCE,
|
ChangeDetectionStrategy,
|
||||||
CHECK_ALWAYS,
|
|
||||||
DETACHED,
|
|
||||||
CHECKED,
|
|
||||||
ON_PUSH,
|
|
||||||
DEFAULT,
|
|
||||||
|
|
||||||
ExpressionChangedAfterItHasBeenCheckedException,
|
ExpressionChangedAfterItHasBeenCheckedException,
|
||||||
ChangeDetectionError,
|
ChangeDetectionError,
|
||||||
|
@ -12,10 +12,9 @@ import {
|
|||||||
} from './exceptions';
|
} from './exceptions';
|
||||||
import {BindingTarget} from './binding_record';
|
import {BindingTarget} from './binding_record';
|
||||||
import {Locals} from './parser/locals';
|
import {Locals} from './parser/locals';
|
||||||
import {CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from './constants';
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile';
|
import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile';
|
||||||
import {isObservable} from './observable_facade';
|
import {isObservable} from './observable_facade';
|
||||||
import {ON_PUSH_OBSERVE} from './constants';
|
|
||||||
|
|
||||||
|
|
||||||
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
|
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
|
||||||
@ -36,7 +35,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
alreadyChecked: any = false;
|
alreadyChecked: any = false;
|
||||||
context: T;
|
context: T;
|
||||||
locals: Locals = null;
|
locals: Locals = null;
|
||||||
mode: string = null;
|
mode: ChangeDetectionStrategy = null;
|
||||||
pipes: Pipes = null;
|
pipes: Pipes = null;
|
||||||
propertyBindingIndex: number;
|
propertyBindingIndex: number;
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
|
|
||||||
constructor(public id: string, public dispatcher: ChangeDispatcher,
|
constructor(public id: string, public dispatcher: ChangeDispatcher,
|
||||||
public numberOfPropertyProtoRecords: number, public bindingTargets: BindingTarget[],
|
public numberOfPropertyProtoRecords: number, public bindingTargets: BindingTarget[],
|
||||||
public directiveIndices: DirectiveIndex[], public strategy: string) {
|
public directiveIndices: DirectiveIndex[], public strategy: ChangeDetectionStrategy) {
|
||||||
this.ref = new ChangeDetectorRef(this);
|
this.ref = new ChangeDetectorRef(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,14 +78,16 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
checkNoChanges(): void { throw new BaseException("Not implemented"); }
|
checkNoChanges(): void { throw new BaseException("Not implemented"); }
|
||||||
|
|
||||||
runDetectChanges(throwOnChange: boolean): void {
|
runDetectChanges(throwOnChange: boolean): void {
|
||||||
if (StringWrapper.equals(this.mode, DETACHED) || StringWrapper.equals(this.mode, CHECKED))
|
if (this.mode === ChangeDetectionStrategy.Detached ||
|
||||||
|
this.mode === ChangeDetectionStrategy.Checked)
|
||||||
return;
|
return;
|
||||||
var s = _scope_check(this.id, throwOnChange);
|
var s = _scope_check(this.id, throwOnChange);
|
||||||
this.detectChangesInRecords(throwOnChange);
|
this.detectChangesInRecords(throwOnChange);
|
||||||
this._detectChangesInLightDomChildren(throwOnChange);
|
this._detectChangesInLightDomChildren(throwOnChange);
|
||||||
if (throwOnChange === false) this.callOnAllChangesDone();
|
if (throwOnChange === false) this.callOnAllChangesDone();
|
||||||
this._detectChangesInShadowDomChildren(throwOnChange);
|
this._detectChangesInShadowDomChildren(throwOnChange);
|
||||||
if (StringWrapper.equals(this.mode, CHECK_ONCE)) this.mode = CHECKED;
|
if (this.mode === ChangeDetectionStrategy.CheckOnce)
|
||||||
|
this.mode = ChangeDetectionStrategy.Checked;
|
||||||
wtfLeave(s);
|
wtfLeave(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +122,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
this.mode = ChangeDetectionUtil.changeDetectionMode(this.strategy);
|
this.mode = ChangeDetectionUtil.changeDetectionMode(this.strategy);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
if (StringWrapper.equals(this.strategy, ON_PUSH_OBSERVE)) {
|
if (this.strategy === ChangeDetectionStrategy.OnPushObserve) {
|
||||||
this.observeComponent(context);
|
this.observeComponent(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
this.dehydrateDirectives(true);
|
this.dehydrateDirectives(true);
|
||||||
|
|
||||||
// This is an experimental feature. Works only in Dart.
|
// This is an experimental feature. Works only in Dart.
|
||||||
if (StringWrapper.equals(this.strategy, ON_PUSH_OBSERVE)) {
|
if (this.strategy === ChangeDetectionStrategy.OnPushObserve) {
|
||||||
this._unsubsribeFromObservables();
|
this._unsubsribeFromObservables();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,12 +172,12 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
markAsCheckOnce(): void { this.mode = CHECK_ONCE; }
|
markAsCheckOnce(): void { this.mode = ChangeDetectionStrategy.CheckOnce; }
|
||||||
|
|
||||||
markPathToRootAsCheckOnce(): void {
|
markPathToRootAsCheckOnce(): void {
|
||||||
var c: ChangeDetector = this;
|
var c: ChangeDetector = this;
|
||||||
while (isPresent(c) && !StringWrapper.equals(c.mode, DETACHED)) {
|
while (isPresent(c) && c.mode !== ChangeDetectionStrategy.Detached) {
|
||||||
if (StringWrapper.equals(c.mode, CHECKED)) c.mode = CHECK_ONCE;
|
if (c.mode === ChangeDetectionStrategy.Checked) c.mode = ChangeDetectionStrategy.CheckOnce;
|
||||||
c = c.parent;
|
c = c.parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export {
|
|||||||
DebugContext,
|
DebugContext,
|
||||||
ChangeDetectorGenConfig
|
ChangeDetectorGenConfig
|
||||||
} from './interfaces';
|
} from './interfaces';
|
||||||
export {CHECK_ONCE, CHECK_ALWAYS, DETACHED, CHECKED, ON_PUSH, DEFAULT} from './constants';
|
export {ChangeDetectionStrategy} from './constants';
|
||||||
export {DynamicProtoChangeDetector} from './proto_change_detector';
|
export {DynamicProtoChangeDetector} from './proto_change_detector';
|
||||||
export {BindingRecord, BindingTarget} from './binding_record';
|
export {BindingRecord, BindingTarget} from './binding_record';
|
||||||
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||||
|
@ -12,6 +12,8 @@ import {codify} from './codegen_facade';
|
|||||||
import {EventBinding} from './event_binding';
|
import {EventBinding} from './event_binding';
|
||||||
import {BindingTarget} from './binding_record';
|
import {BindingTarget} from './binding_record';
|
||||||
import {ChangeDetectorGenConfig} from './interfaces';
|
import {ChangeDetectorGenConfig} from './interfaces';
|
||||||
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,7 +35,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
_names: CodegenNameUtil;
|
_names: CodegenNameUtil;
|
||||||
_typeName: string;
|
_typeName: string;
|
||||||
|
|
||||||
constructor(private id: string, private changeDetectionStrategy: string,
|
constructor(private id: string, private changeDetectionStrategy: ChangeDetectionStrategy,
|
||||||
private records: List<ProtoRecord>, private propertyBindingTargets: BindingTarget[],
|
private records: List<ProtoRecord>, private propertyBindingTargets: BindingTarget[],
|
||||||
private eventBindings: EventBinding[], private directiveRecords: List<any>,
|
private eventBindings: EventBinding[], private directiveRecords: List<any>,
|
||||||
private genConfig: ChangeDetectorGenConfig) {
|
private genConfig: ChangeDetectorGenConfig) {
|
||||||
|
@ -8,13 +8,7 @@ import {
|
|||||||
} from 'angular2/src/core/facade/lang';
|
} from 'angular2/src/core/facade/lang';
|
||||||
import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {ProtoRecord} from './proto_record';
|
import {ProtoRecord} from './proto_record';
|
||||||
import {
|
import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants';
|
||||||
CHECK_ALWAYS,
|
|
||||||
CHECK_ONCE,
|
|
||||||
CHECKED,
|
|
||||||
DETACHED,
|
|
||||||
isDefaultChangeDetectionStrategy
|
|
||||||
} from './constants';
|
|
||||||
import {implementsOnDestroy} from './pipe_lifecycle_reflector';
|
import {implementsOnDestroy} from './pipe_lifecycle_reflector';
|
||||||
import {BindingTarget} from './binding_record';
|
import {BindingTarget} from './binding_record';
|
||||||
import {DirectiveIndex} from './directive_record';
|
import {DirectiveIndex} from './directive_record';
|
||||||
@ -180,8 +174,9 @@ export class ChangeDetectionUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static changeDetectionMode(strategy: string): string {
|
static changeDetectionMode(strategy: ChangeDetectionStrategy): ChangeDetectionStrategy {
|
||||||
return isDefaultChangeDetectionStrategy(strategy) ? CHECK_ALWAYS : CHECK_ONCE;
|
return isDefaultChangeDetectionStrategy(strategy) ? ChangeDetectionStrategy.CheckAlways :
|
||||||
|
ChangeDetectionStrategy.CheckOnce;
|
||||||
}
|
}
|
||||||
|
|
||||||
static simpleChange(previousValue: any, currentValue: any): SimpleChange {
|
static simpleChange(previousValue: any, currentValue: any): SimpleChange {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {ChangeDetector} from './interfaces';
|
import {ChangeDetector} from './interfaces';
|
||||||
import {CHECK_ONCE, DETACHED, CHECK_ALWAYS} from './constants';
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls change detection.
|
* Controls change detection.
|
||||||
@ -14,7 +14,7 @@ export class ChangeDetectorRef {
|
|||||||
constructor(private _cd: ChangeDetector) {}
|
constructor(private _cd: ChangeDetector) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to check all ON_PUSH ancestors.
|
* Request to check all OnPush ancestors.
|
||||||
*/
|
*/
|
||||||
requestCheck(): void { this._cd.markPathToRootAsCheckOnce(); }
|
requestCheck(): void { this._cd.markPathToRootAsCheckOnce(); }
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export class ChangeDetectorRef {
|
|||||||
*
|
*
|
||||||
* The detached change detector will not be checked until it is reattached.
|
* The detached change detector will not be checked until it is reattached.
|
||||||
*/
|
*/
|
||||||
detach(): void { this._cd.mode = DETACHED; }
|
detach(): void { this._cd.mode = ChangeDetectionStrategy.Detached; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reattach the change detector to the change detector tree.
|
* Reattach the change detector to the change detector tree.
|
||||||
@ -33,7 +33,7 @@ export class ChangeDetectorRef {
|
|||||||
* next change detection run.
|
* next change detection run.
|
||||||
*/
|
*/
|
||||||
reattach(): void {
|
reattach(): void {
|
||||||
this._cd.mode = CHECK_ALWAYS;
|
this._cd.mode = ChangeDetectionStrategy.CheckAlways;
|
||||||
this.requestCheck();
|
this.requestCheck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,14 @@ import {codify, combineGeneratedStrings, rawString} from './codegen_facade';
|
|||||||
import {ProtoRecord, RecordType} from './proto_record';
|
import {ProtoRecord, RecordType} from './proto_record';
|
||||||
import {BindingTarget} from './binding_record';
|
import {BindingTarget} from './binding_record';
|
||||||
import {DirectiveRecord} from './directive_record';
|
import {DirectiveRecord} from './directive_record';
|
||||||
import {ON_PUSH_OBSERVE} from './constants';
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class responsible for providing change detection logic for chagne detector classes.
|
* Class responsible for providing change detection logic for chagne detector classes.
|
||||||
*/
|
*/
|
||||||
export class CodegenLogicUtil {
|
export class CodegenLogicUtil {
|
||||||
constructor(private _names: CodegenNameUtil, private _utilName: string,
|
constructor(private _names: CodegenNameUtil, private _utilName: string,
|
||||||
private _changeDetection: string) {}
|
private _changeDetection: ChangeDetectionStrategy) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a statement which updates the local variable representing `protoRec` with the current
|
* Generates a statement which updates the local variable representing `protoRec` with the current
|
||||||
@ -119,7 +119,7 @@ export class CodegenLogicUtil {
|
|||||||
|
|
||||||
_observe(exp: string, rec: ProtoRecord): string {
|
_observe(exp: string, rec: ProtoRecord): string {
|
||||||
// This is an experimental feature. Works only in Dart.
|
// This is an experimental feature. Works only in Dart.
|
||||||
if (StringWrapper.equals(this._changeDetection, ON_PUSH_OBSERVE)) {
|
if (this._changeDetection === ChangeDetectionStrategy.OnPushObserve) {
|
||||||
return `this.observeValue(${exp}, ${rec.selfIndex})`;
|
return `this.observeValue(${exp}, ${rec.selfIndex})`;
|
||||||
} else {
|
} else {
|
||||||
return exp;
|
return exp;
|
||||||
@ -165,7 +165,7 @@ export class CodegenLogicUtil {
|
|||||||
|
|
||||||
private _genReadDirective(index: number) {
|
private _genReadDirective(index: number) {
|
||||||
// This is an experimental feature. Works only in Dart.
|
// This is an experimental feature. Works only in Dart.
|
||||||
if (StringWrapper.equals(this._changeDetection, ON_PUSH_OBSERVE)) {
|
if (this._changeDetection === ChangeDetectionStrategy.OnPushObserve) {
|
||||||
return `this.observeDirective(this.getDirectiveFor(directives, ${index}), ${index})`;
|
return `this.observeDirective(this.getDirectiveFor(directives, ${index}), ${index})`;
|
||||||
} else {
|
} else {
|
||||||
return `this.getDirectiveFor(directives, ${index})`;
|
return `this.getDirectiveFor(directives, ${index})`;
|
||||||
|
@ -1,46 +1,49 @@
|
|||||||
// TODO:vsavkin Use enums after switching to TypeScript
|
// TODO:vsavkin Use enums after switching to TypeScript
|
||||||
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
||||||
|
|
||||||
/**
|
export enum ChangeDetectionStrategy {
|
||||||
* CHECK_ONCE means that after calling detectChanges the mode of the change detector
|
/**
|
||||||
* will become CHECKED.
|
* `CheckedOnce` means that after calling detectChanges the mode of the change detector
|
||||||
*/
|
* will become `Checked`.
|
||||||
export const CHECK_ONCE: string = "CHECK_ONCE";
|
*/
|
||||||
|
CheckOnce,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CHECKED means that the change detector should be skipped until its mode changes to
|
* `Checked` means that the change detector should be skipped until its mode changes to
|
||||||
* CHECK_ONCE or CHECK_ALWAYS.
|
* `CheckOnce`.
|
||||||
*/
|
*/
|
||||||
export const CHECKED: string = "CHECKED";
|
Checked,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CHECK_ALWAYS means that after calling detectChanges the mode of the change detector
|
* `CheckAlways` means that after calling detectChanges the mode of the change detector
|
||||||
* will remain CHECK_ALWAYS.
|
* will remain `CheckAlways`.
|
||||||
*/
|
*/
|
||||||
export const CHECK_ALWAYS: string = "ALWAYS_CHECK";
|
CheckAlways,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DETACHED means that the change detector sub tree is not a part of the main tree and
|
* `Detached` means that the change detector sub tree is not a part of the main tree and
|
||||||
* should be skipped.
|
* should be skipped.
|
||||||
*/
|
*/
|
||||||
export const DETACHED: string = "DETACHED";
|
Detached,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ON_PUSH means that the change detector's mode will be set to CHECK_ONCE during hydration.
|
* `OnPush` means that the change detector's mode will be set to `CheckOnce` during hydration.
|
||||||
*/
|
*/
|
||||||
export const ON_PUSH: string = "ON_PUSH";
|
OnPush,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DEFAULT means that the change detector's mode will be set to CHECK_ALWAYS during hydration.
|
* `Default` means that the change detector's mode will be set to `CheckAlways` during hydration.
|
||||||
*/
|
*/
|
||||||
export const DEFAULT: string = "DEFAULT";
|
Default,
|
||||||
|
|
||||||
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: string): boolean {
|
/**
|
||||||
return isBlank(changeDetectionStrategy) || StringWrapper.equals(changeDetectionStrategy, DEFAULT);
|
* This is an experimental feature. Works only in Dart.
|
||||||
|
*/
|
||||||
|
OnPushObserve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: ChangeDetectionStrategy):
|
||||||
/**
|
boolean {
|
||||||
* This is an experimental feature. Works only in Dart.
|
return isBlank(changeDetectionStrategy) ||
|
||||||
*/
|
changeDetectionStrategy === ChangeDetectionStrategy.Default;
|
||||||
export const ON_PUSH_OBSERVE = "ON_PUSH_OBSERVE";
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
||||||
import {isDefaultChangeDetectionStrategy} from './constants';
|
import {isDefaultChangeDetectionStrategy, ChangeDetectionStrategy} from './constants';
|
||||||
|
|
||||||
export class DirectiveIndex {
|
export class DirectiveIndex {
|
||||||
constructor(public elementIndex: number, public directiveIndex: number) {}
|
constructor(public elementIndex: number, public directiveIndex: number) {}
|
||||||
@ -13,7 +13,7 @@ export class DirectiveRecord {
|
|||||||
callOnChange: boolean;
|
callOnChange: boolean;
|
||||||
callOnCheck: boolean;
|
callOnCheck: boolean;
|
||||||
callOnInit: boolean;
|
callOnInit: boolean;
|
||||||
changeDetection: string;
|
changeDetection: ChangeDetectionStrategy;
|
||||||
|
|
||||||
constructor({directiveIndex, callOnAllChangesDone, callOnChange, callOnCheck, callOnInit,
|
constructor({directiveIndex, callOnAllChangesDone, callOnChange, callOnCheck, callOnInit,
|
||||||
changeDetection}: {
|
changeDetection}: {
|
||||||
@ -22,7 +22,7 @@ export class DirectiveRecord {
|
|||||||
callOnChange?: boolean,
|
callOnChange?: boolean,
|
||||||
callOnCheck?: boolean,
|
callOnCheck?: boolean,
|
||||||
callOnInit?: boolean,
|
callOnInit?: boolean,
|
||||||
changeDetection?: string
|
changeDetection?: ChangeDetectionStrategy
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.directiveIndex = directiveIndex;
|
this.directiveIndex = directiveIndex;
|
||||||
this.callOnAllChangesDone = normalizeBool(callOnAllChangesDone);
|
this.callOnAllChangesDone = normalizeBool(callOnAllChangesDone);
|
||||||
@ -35,4 +35,4 @@ export class DirectiveRecord {
|
|||||||
isDefaultChangeDetection(): boolean {
|
isDefaultChangeDetection(): boolean {
|
||||||
return isDefaultChangeDetectionStrategy(this.changeDetection);
|
return isDefaultChangeDetectionStrategy(this.changeDetection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import {DirectiveRecord, DirectiveIndex} from './directive_record';
|
|||||||
import {Locals} from './parser/locals';
|
import {Locals} from './parser/locals';
|
||||||
import {ChangeDetectorGenConfig} from './interfaces';
|
import {ChangeDetectorGenConfig} from './interfaces';
|
||||||
import {ChangeDetectionUtil, SimpleChange} from './change_detection_util';
|
import {ChangeDetectionUtil, SimpleChange} from './change_detection_util';
|
||||||
import {ON_PUSH_OBSERVE} from './constants';
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
import {ProtoRecord, RecordType} from './proto_record';
|
import {ProtoRecord, RecordType} from './proto_record';
|
||||||
|
|
||||||
export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||||
@ -26,7 +26,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
|
|
||||||
constructor(id: string, dispatcher: any, numberOfPropertyProtoRecords: number,
|
constructor(id: string, dispatcher: any, numberOfPropertyProtoRecords: number,
|
||||||
propertyBindingTargets: BindingTarget[], directiveIndices: DirectiveIndex[],
|
propertyBindingTargets: BindingTarget[], directiveIndices: DirectiveIndex[],
|
||||||
strategy: string, private records: ProtoRecord[],
|
strategy: ChangeDetectionStrategy, private records: ProtoRecord[],
|
||||||
private eventBindings: EventBinding[], private directiveRecords: DirectiveRecord[],
|
private eventBindings: EventBinding[], private directiveRecords: DirectiveRecord[],
|
||||||
private genConfig: ChangeDetectorGenConfig) {
|
private genConfig: ChangeDetectorGenConfig) {
|
||||||
super(id, dispatcher, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices,
|
super(id, dispatcher, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices,
|
||||||
@ -88,7 +88,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
this.values[0] = this.context;
|
this.values[0] = this.context;
|
||||||
this.directives = directives;
|
this.directives = directives;
|
||||||
|
|
||||||
if (StringWrapper.equals(this.strategy, ON_PUSH_OBSERVE)) {
|
if (this.strategy === ChangeDetectionStrategy.OnPushObserve) {
|
||||||
for (var i = 0; i < this.directiveIndices.length; ++i) {
|
for (var i = 0; i < this.directiveIndices.length; ++i) {
|
||||||
var index = this.directiveIndices[i];
|
var index = this.directiveIndices[i];
|
||||||
super.observeDirective(directives.getDirectiveFor(index), i);
|
super.observeDirective(directives.getDirectiveFor(index), i);
|
||||||
@ -219,7 +219,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var currValue = this._calculateCurrValue(proto, values, locals);
|
var currValue = this._calculateCurrValue(proto, values, locals);
|
||||||
if (StringWrapper.equals(this.strategy, ON_PUSH_OBSERVE)) {
|
if (this.strategy === ChangeDetectionStrategy.OnPushObserve) {
|
||||||
super.observeValue(currValue, proto.selfIndex);
|
super.observeValue(currValue, proto.selfIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import {CONST} from 'angular2/src/core/facade/lang';
|
|||||||
import {Locals} from './parser/locals';
|
import {Locals} from './parser/locals';
|
||||||
import {BindingTarget, BindingRecord} from './binding_record';
|
import {BindingTarget, BindingRecord} from './binding_record';
|
||||||
import {DirectiveIndex, DirectiveRecord} from './directive_record';
|
import {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||||
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
import {ChangeDetectorRef} from './change_detector_ref';
|
import {ChangeDetectorRef} from './change_detector_ref';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,7 +56,7 @@ export interface ChangeDispatcher {
|
|||||||
|
|
||||||
export interface ChangeDetector {
|
export interface ChangeDetector {
|
||||||
parent: ChangeDetector;
|
parent: ChangeDetector;
|
||||||
mode: string;
|
mode: ChangeDetectionStrategy;
|
||||||
ref: ChangeDetectorRef;
|
ref: ChangeDetectorRef;
|
||||||
|
|
||||||
addChild(cd: ChangeDetector): void;
|
addChild(cd: ChangeDetector): void;
|
||||||
@ -80,8 +81,8 @@ export class ChangeDetectorGenConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ChangeDetectorDefinition {
|
export class ChangeDetectorDefinition {
|
||||||
constructor(public id: string, public strategy: string, public variableNames: List<string>,
|
constructor(public id: string, public strategy: ChangeDetectionStrategy,
|
||||||
public bindingRecords: BindingRecord[], public eventRecords: BindingRecord[],
|
public variableNames: List<string>, public bindingRecords: BindingRecord[],
|
||||||
public directiveRecords: DirectiveRecord[],
|
public eventRecords: BindingRecord[], public directiveRecords: DirectiveRecord[],
|
||||||
public genConfig: ChangeDetectorGenConfig) {}
|
public genConfig: ChangeDetectorGenConfig) {}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ export 'dart:core' show List;
|
|||||||
export 'package:angular2/src/core/change_detection/abstract_change_detector.dart'
|
export 'package:angular2/src/core/change_detection/abstract_change_detector.dart'
|
||||||
show AbstractChangeDetector;
|
show AbstractChangeDetector;
|
||||||
export 'package:angular2/src/core/change_detection/change_detection.dart'
|
export 'package:angular2/src/core/change_detection/change_detection.dart'
|
||||||
show preGeneratedProtoDetectors;
|
show preGeneratedProtoDetectors, ChangeDetectionStrategy;
|
||||||
export 'package:angular2/src/core/change_detection/directive_record.dart'
|
export 'package:angular2/src/core/change_detection/directive_record.dart'
|
||||||
show DirectiveIndex, DirectiveRecord;
|
show DirectiveIndex, DirectiveRecord;
|
||||||
export 'package:angular2/src/core/change_detection/interfaces.dart'
|
export 'package:angular2/src/core/change_detection/interfaces.dart'
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
BindingRecord,
|
BindingRecord,
|
||||||
DirectiveRecord,
|
DirectiveRecord,
|
||||||
ProtoChangeDetector,
|
ProtoChangeDetector,
|
||||||
DEFAULT,
|
ChangeDetectionStrategy,
|
||||||
ChangeDetectorDefinition,
|
ChangeDetectorDefinition,
|
||||||
ChangeDetectorGenConfig,
|
ChangeDetectorGenConfig,
|
||||||
ASTWithSource
|
ASTWithSource
|
||||||
@ -305,7 +305,7 @@ function _getChangeDetectorDefinitions(
|
|||||||
bindingRecordsCreator.getEventBindingRecords(elementBinders, allRenderDirectiveMetadata);
|
bindingRecordsCreator.getEventBindingRecords(elementBinders, allRenderDirectiveMetadata);
|
||||||
var directiveRecords =
|
var directiveRecords =
|
||||||
bindingRecordsCreator.getDirectiveRecords(elementBinders, allRenderDirectiveMetadata);
|
bindingRecordsCreator.getDirectiveRecords(elementBinders, allRenderDirectiveMetadata);
|
||||||
var strategyName = DEFAULT;
|
var strategyName = ChangeDetectionStrategy.Default;
|
||||||
if (pvWithIndex.renderProtoView.type === ViewType.COMPONENT) {
|
if (pvWithIndex.renderProtoView.type === ViewType.COMPONENT) {
|
||||||
strategyName = hostComponentMetadata.changeDetection;
|
strategyName = hostComponentMetadata.changeDetection;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
library angular2.src.core.metadata;
|
library angular2.src.core.metadata;
|
||||||
|
|
||||||
import "package:angular2/src/core/facade/collection.dart" show List;
|
import "package:angular2/src/core/facade/collection.dart" show List;
|
||||||
|
import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||||
import "./metadata/di.dart";
|
import "./metadata/di.dart";
|
||||||
import "./metadata/directives.dart";
|
import "./metadata/directives.dart";
|
||||||
import "./metadata/view.dart";
|
import "./metadata/view.dart";
|
||||||
@ -35,7 +36,7 @@ class Component extends ComponentMetadata {
|
|||||||
const Component({String selector, List<String> properties,
|
const Component({String selector, List<String> properties,
|
||||||
List<String> events, Map<String, String> host,
|
List<String> events, Map<String, String> host,
|
||||||
List<LifecycleEvent> lifecycle, List bindings, String exportAs,
|
List<LifecycleEvent> lifecycle, List bindings, String exportAs,
|
||||||
bool compileChildren, List viewBindings, String changeDetection})
|
bool compileChildren, List viewBindings, ChangeDetectionStrategy changeDetection})
|
||||||
: super(
|
: super(
|
||||||
selector: selector,
|
selector: selector,
|
||||||
properties: properties,
|
properties: properties,
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
} from './metadata/directives';
|
} from './metadata/directives';
|
||||||
|
|
||||||
import {ViewMetadata, ViewEncapsulation} from './metadata/view';
|
import {ViewMetadata, ViewEncapsulation} from './metadata/view';
|
||||||
|
import {ChangeDetectionStrategy} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
import {makeDecorator, makeParamDecorator, TypeDecorator, Class} from './util/decorators';
|
import {makeDecorator, makeParamDecorator, TypeDecorator, Class} from './util/decorators';
|
||||||
import {Type} from 'angular2/src/core/facade/lang';
|
import {Type} from 'angular2/src/core/facade/lang';
|
||||||
@ -191,7 +192,7 @@ export interface ComponentFactory {
|
|||||||
exportAs?: string,
|
exportAs?: string,
|
||||||
compileChildren?: boolean,
|
compileChildren?: boolean,
|
||||||
viewBindings?: List<any>,
|
viewBindings?: List<any>,
|
||||||
changeDetection?: string,
|
changeDetection?: ChangeDetectionStrategy,
|
||||||
}): ComponentDecorator;
|
}): ComponentDecorator;
|
||||||
new (obj: {
|
new (obj: {
|
||||||
selector?: string,
|
selector?: string,
|
||||||
@ -203,7 +204,7 @@ export interface ComponentFactory {
|
|||||||
exportAs?: string,
|
exportAs?: string,
|
||||||
compileChildren?: boolean,
|
compileChildren?: boolean,
|
||||||
viewBindings?: List<any>,
|
viewBindings?: List<any>,
|
||||||
changeDetection?: string,
|
changeDetection?: ChangeDetectionStrategy,
|
||||||
}): ComponentMetadata;
|
}): ComponentMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {CONST, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
import {CONST, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||||
import {List} from 'angular2/src/core/facade/collection';
|
import {List} from 'angular2/src/core/facade/collection';
|
||||||
import {InjectableMetadata} from 'angular2/src/core/di/metadata';
|
import {InjectableMetadata} from 'angular2/src/core/di/metadata';
|
||||||
import {DEFAULT} from 'angular2/change_detection';
|
import {ChangeDetectionStrategy} from 'angular2/change_detection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directives allow you to attach behavior to elements in the DOM.
|
* Directives allow you to attach behavior to elements in the DOM.
|
||||||
@ -795,14 +795,12 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||||||
* Defines the used change detection strategy.
|
* Defines the used change detection strategy.
|
||||||
*
|
*
|
||||||
* When a component is instantiated, Angular creates a change detector, which is responsible for
|
* When a component is instantiated, Angular creates a change detector, which is responsible for
|
||||||
* propagating
|
* propagating the component's bindings.
|
||||||
* the component's bindings.
|
|
||||||
*
|
*
|
||||||
* The `changeDetection` property defines, whether the change detection will be checked every time
|
* The `changeDetection` property defines, whether the change detection will be checked every time
|
||||||
* or only when the component
|
* or only when the component tells it to do so.
|
||||||
* tells it to do so.
|
|
||||||
*/
|
*/
|
||||||
changeDetection: string;
|
changeDetection: ChangeDetectionStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the set of injectable objects that are visible to its view dom children.
|
* Defines the set of injectable objects that are visible to its view dom children.
|
||||||
@ -847,7 +845,7 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||||||
viewBindings: List<any>;
|
viewBindings: List<any>;
|
||||||
|
|
||||||
constructor({selector, properties, events, host, exportAs, lifecycle, bindings, viewBindings,
|
constructor({selector, properties, events, host, exportAs, lifecycle, bindings, viewBindings,
|
||||||
changeDetection = DEFAULT, compileChildren = true}: {
|
changeDetection = ChangeDetectionStrategy.Default, compileChildren = true}: {
|
||||||
selector?: string,
|
selector?: string,
|
||||||
properties?: List<string>,
|
properties?: List<string>,
|
||||||
events?: List<string>,
|
events?: List<string>,
|
||||||
@ -857,7 +855,7 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||||||
exportAs?: string,
|
exportAs?: string,
|
||||||
compileChildren?: boolean,
|
compileChildren?: boolean,
|
||||||
viewBindings?: List<any>,
|
viewBindings?: List<any>,
|
||||||
changeDetection?: string,
|
changeDetection?: ChangeDetectionStrategy,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
super({
|
super({
|
||||||
selector: selector,
|
selector: selector,
|
||||||
|
@ -46,7 +46,7 @@ var _observableStrategy = new ObservableStrategy();
|
|||||||
* ```
|
* ```
|
||||||
* @Component({
|
* @Component({
|
||||||
* selector: "task-cmp",
|
* selector: "task-cmp",
|
||||||
* changeDetection: ON_PUSH
|
* changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
* })
|
* })
|
||||||
* @View({
|
* @View({
|
||||||
* template: "Task Description {{ description | async }}"
|
* template: "Task Description {{ description | async }}"
|
||||||
|
@ -7,7 +7,10 @@ import {
|
|||||||
StringMap,
|
StringMap,
|
||||||
StringMapWrapper
|
StringMapWrapper
|
||||||
} from 'angular2/src/core/facade/collection';
|
} from 'angular2/src/core/facade/collection';
|
||||||
import {ASTWithSource} from 'angular2/src/core/change_detection/change_detection';
|
import {
|
||||||
|
ASTWithSource,
|
||||||
|
ChangeDetectionStrategy
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General notes:
|
* General notes:
|
||||||
@ -155,7 +158,7 @@ export class RenderDirectiveMetadata {
|
|||||||
callOnCheck: boolean;
|
callOnCheck: boolean;
|
||||||
callOnInit: boolean;
|
callOnInit: boolean;
|
||||||
callOnAllChangesDone: boolean;
|
callOnAllChangesDone: boolean;
|
||||||
changeDetection: string;
|
changeDetection: ChangeDetectionStrategy;
|
||||||
exportAs: string;
|
exportAs: string;
|
||||||
hostListeners: Map<string, string>;
|
hostListeners: Map<string, string>;
|
||||||
hostProperties: Map<string, string>;
|
hostProperties: Map<string, string>;
|
||||||
@ -185,7 +188,7 @@ export class RenderDirectiveMetadata {
|
|||||||
callOnCheck?: boolean,
|
callOnCheck?: boolean,
|
||||||
callOnInit?: boolean,
|
callOnInit?: boolean,
|
||||||
callOnAllChangesDone?: boolean,
|
callOnAllChangesDone?: boolean,
|
||||||
changeDetection?: string,
|
changeDetection?: ChangeDetectionStrategy,
|
||||||
exportAs?: string
|
exportAs?: string
|
||||||
}) {
|
}) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@ -224,7 +227,7 @@ export class RenderDirectiveMetadata {
|
|||||||
callOnCheck?: boolean,
|
callOnCheck?: boolean,
|
||||||
callOnInit?: boolean,
|
callOnInit?: boolean,
|
||||||
callOnAllChangesDone?: boolean,
|
callOnAllChangesDone?: boolean,
|
||||||
changeDetection?: string,
|
changeDetection?: ChangeDetectionStrategy,
|
||||||
exportAs?: string
|
exportAs?: string
|
||||||
}): RenderDirectiveMetadata {
|
}): RenderDirectiveMetadata {
|
||||||
let hostListeners = new Map();
|
let hostListeners = new Map();
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
import {ListWrapper, MapWrapper} from 'angular2/src/core/facade/collection';
|
|
||||||
import {isPresent, isArray} from 'angular2/src/core/facade/lang';
|
|
||||||
import {RenderDirectiveMetadata} from 'angular2/src/core/render/api';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a [DirectiveMetadata] to a map representation. This creates a copy,
|
|
||||||
* that is, subsequent changes to `meta` will not be mirrored in the map.
|
|
||||||
*/
|
|
||||||
export function directiveMetadataToMap(meta: RenderDirectiveMetadata): Map<string, any> {
|
|
||||||
return MapWrapper.createFromPairs([
|
|
||||||
['id', meta.id],
|
|
||||||
['selector', meta.selector],
|
|
||||||
['compileChildren', meta.compileChildren],
|
|
||||||
['hostProperties', _cloneIfPresent(meta.hostProperties)],
|
|
||||||
['hostListeners', _cloneIfPresent(meta.hostListeners)],
|
|
||||||
['hostActions', _cloneIfPresent(meta.hostActions)],
|
|
||||||
['hostAttributes', _cloneIfPresent(meta.hostAttributes)],
|
|
||||||
['properties', _cloneIfPresent(meta.properties)],
|
|
||||||
['readAttributes', _cloneIfPresent(meta.readAttributes)],
|
|
||||||
['type', meta.type],
|
|
||||||
['exportAs', meta.exportAs],
|
|
||||||
['callOnDestroy', meta.callOnDestroy],
|
|
||||||
['callOnCheck', meta.callOnCheck],
|
|
||||||
['callOnInit', meta.callOnInit],
|
|
||||||
['callOnChange', meta.callOnChange],
|
|
||||||
['callOnAllChangesDone', meta.callOnAllChangesDone],
|
|
||||||
['events', meta.events],
|
|
||||||
['changeDetection', meta.changeDetection],
|
|
||||||
['version', 1],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a map representation of [DirectiveMetadata] into a
|
|
||||||
* [DirectiveMetadata] object. This creates a copy, that is, subsequent changes
|
|
||||||
* to `map` will not be mirrored in the [DirectiveMetadata] object.
|
|
||||||
*/
|
|
||||||
export function directiveMetadataFromMap(map: Map<string, any>): RenderDirectiveMetadata {
|
|
||||||
return new RenderDirectiveMetadata({
|
|
||||||
id:<string>map.get('id'),
|
|
||||||
selector:<string>map.get('selector'),
|
|
||||||
compileChildren:<boolean>map.get('compileChildren'),
|
|
||||||
hostProperties:<Map<string, string>>_cloneIfPresent(map.get('hostProperties')),
|
|
||||||
hostListeners:<Map<string, string>>_cloneIfPresent(map.get('hostListeners')),
|
|
||||||
hostActions:<Map<string, string>>_cloneIfPresent(map.get('hostActions')),
|
|
||||||
hostAttributes:<Map<string, string>>_cloneIfPresent(map.get('hostAttributes')),
|
|
||||||
properties:<List<string>>_cloneIfPresent(map.get('properties')),
|
|
||||||
readAttributes:<List<string>>_cloneIfPresent(map.get('readAttributes')),
|
|
||||||
type:<number>map.get('type'),
|
|
||||||
exportAs:<string>map.get('exportAs'),
|
|
||||||
callOnDestroy:<boolean>map.get('callOnDestroy'),
|
|
||||||
callOnCheck:<boolean>map.get('callOnCheck'),
|
|
||||||
callOnChange:<boolean>map.get('callOnChange'),
|
|
||||||
callOnInit:<boolean>map.get('callOnInit'),
|
|
||||||
callOnAllChangesDone:<boolean>map.get('callOnAllChangesDone'),
|
|
||||||
events:<List<string>>_cloneIfPresent(map.get('events')),
|
|
||||||
changeDetection:<string>map.get('changeDetection'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clones the [List] or [Map] `o` if it is present.
|
|
||||||
*/
|
|
||||||
function _cloneIfPresent(o): any {
|
|
||||||
if (!isPresent(o)) return null;
|
|
||||||
return isArray(o) ? ListWrapper.clone(o) : MapWrapper.clone(o);
|
|
||||||
}
|
|
@ -1,8 +1,7 @@
|
|||||||
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {isBlank, isPresent} from 'angular2/src/core/facade/lang';
|
import {isBlank, isPresent} from 'angular2/src/core/facade/lang';
|
||||||
import {
|
import {
|
||||||
DEFAULT,
|
ChangeDetectionStrategy,
|
||||||
ON_PUSH,
|
|
||||||
BindingRecord,
|
BindingRecord,
|
||||||
ChangeDetectorDefinition,
|
ChangeDetectorDefinition,
|
||||||
DirectiveIndex,
|
DirectiveIndex,
|
||||||
@ -12,7 +11,6 @@ import {
|
|||||||
Parser,
|
Parser,
|
||||||
ChangeDetectorGenConfig
|
ChangeDetectorGenConfig
|
||||||
} from 'angular2/src/core/change_detection/change_detection';
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
import {ON_PUSH_OBSERVE} from 'angular2/src/core/change_detection/constants';
|
|
||||||
import {reflector} from 'angular2/src/core/reflection/reflection';
|
import {reflector} from 'angular2/src/core/reflection/reflection';
|
||||||
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
|
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
|
||||||
|
|
||||||
@ -109,15 +107,17 @@ export function getDefinition(id: string): TestDefinition {
|
|||||||
|
|
||||||
} else if (id == "onPushObserveBinding") {
|
} else if (id == "onPushObserveBinding") {
|
||||||
var records = _createBindingRecords("a");
|
var records = _createBindingRecords("a");
|
||||||
let cdDef = new ChangeDetectorDefinition(id, ON_PUSH_OBSERVE, [], records, [], [], genConfig);
|
let cdDef = new ChangeDetectorDefinition(id, ChangeDetectionStrategy.OnPushObserve, [], records,
|
||||||
|
[], [], genConfig);
|
||||||
testDef = new TestDefinition(id, cdDef, null);
|
testDef = new TestDefinition(id, cdDef, null);
|
||||||
|
|
||||||
} else if (id == "onPushObserveComponent") {
|
} else if (id == "onPushObserveComponent") {
|
||||||
let cdDef = new ChangeDetectorDefinition(id, ON_PUSH_OBSERVE, [], [], [], [], genConfig);
|
let cdDef = new ChangeDetectorDefinition(id, ChangeDetectionStrategy.OnPushObserve, [], [], [],
|
||||||
|
[], genConfig);
|
||||||
testDef = new TestDefinition(id, cdDef, null);
|
testDef = new TestDefinition(id, cdDef, null);
|
||||||
|
|
||||||
} else if (id == "onPushObserveDirective") {
|
} else if (id == "onPushObserveDirective") {
|
||||||
let cdDef = new ChangeDetectorDefinition(id, ON_PUSH_OBSERVE, [], [], [],
|
let cdDef = new ChangeDetectorDefinition(id, ChangeDetectionStrategy.OnPushObserve, [], [], [],
|
||||||
[_DirectiveUpdating.recordNoCallbacks], genConfig);
|
[_DirectiveUpdating.recordNoCallbacks], genConfig);
|
||||||
testDef = new TestDefinition(id, cdDef, null);
|
testDef = new TestDefinition(id, cdDef, null);
|
||||||
} else if (id == "updateElementProduction") {
|
} else if (id == "updateElementProduction") {
|
||||||
@ -196,7 +196,7 @@ class _ExpressionWithLocals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ExpressionWithMode {
|
class _ExpressionWithMode {
|
||||||
constructor(private _strategy: string, private _withRecords: boolean,
|
constructor(private _strategy: ChangeDetectionStrategy, private _withRecords: boolean,
|
||||||
private _withEvents: boolean) {}
|
private _withEvents: boolean) {}
|
||||||
|
|
||||||
createChangeDetectorDefinition(): ChangeDetectorDefinition {
|
createChangeDetectorDefinition(): ChangeDetectorDefinition {
|
||||||
@ -205,10 +205,14 @@ class _ExpressionWithMode {
|
|||||||
var directiveRecords = [];
|
var directiveRecords = [];
|
||||||
var eventRecords = [];
|
var eventRecords = [];
|
||||||
|
|
||||||
var dirRecordWithDefault =
|
var dirRecordWithDefault = new DirectiveRecord({
|
||||||
new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 0), changeDetection: DEFAULT});
|
directiveIndex: new DirectiveIndex(0, 0),
|
||||||
var dirRecordWithOnPush =
|
changeDetection: ChangeDetectionStrategy.Default
|
||||||
new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 1), changeDetection: ON_PUSH});
|
});
|
||||||
|
var dirRecordWithOnPush = new DirectiveRecord({
|
||||||
|
directiveIndex: new DirectiveIndex(0, 1),
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
});
|
||||||
|
|
||||||
if (this._withRecords) {
|
if (this._withRecords) {
|
||||||
var updateDirWithOnDefaultRecord =
|
var updateDirWithOnDefaultRecord =
|
||||||
@ -240,11 +244,14 @@ class _ExpressionWithMode {
|
|||||||
* Definitions in this map define conditions which allow testing various change detector modes.
|
* Definitions in this map define conditions which allow testing various change detector modes.
|
||||||
*/
|
*/
|
||||||
static availableDefinitions: StringMap<string, _ExpressionWithMode> = {
|
static availableDefinitions: StringMap<string, _ExpressionWithMode> = {
|
||||||
'emptyUsingDefaultStrategy': new _ExpressionWithMode(DEFAULT, false, false),
|
'emptyUsingDefaultStrategy':
|
||||||
'emptyUsingOnPushStrategy': new _ExpressionWithMode(ON_PUSH, false, false),
|
new _ExpressionWithMode(ChangeDetectionStrategy.Default, false, false),
|
||||||
'onPushRecordsUsingDefaultStrategy': new _ExpressionWithMode(DEFAULT, true, false),
|
'emptyUsingOnPushStrategy':
|
||||||
'onPushWithEvent': new _ExpressionWithMode(ON_PUSH, false, true),
|
new _ExpressionWithMode(ChangeDetectionStrategy.OnPush, false, false),
|
||||||
'onPushWithHostEvent': new _ExpressionWithMode(ON_PUSH, false, true)
|
'onPushRecordsUsingDefaultStrategy':
|
||||||
|
new _ExpressionWithMode(ChangeDetectionStrategy.Default, true, false),
|
||||||
|
'onPushWithEvent': new _ExpressionWithMode(ChangeDetectionStrategy.OnPush, false, true),
|
||||||
|
'onPushWithHostEvent': new _ExpressionWithMode(ChangeDetectionStrategy.OnPush, false, true)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,4 +420,4 @@ var _availableEventDefinitions = [
|
|||||||
'(event)="true"'
|
'(event)="true"'
|
||||||
];
|
];
|
||||||
|
|
||||||
var _availableHostEventDefinitions = ['(host-event)="onEvent(\$event)"'];
|
var _availableHostEventDefinitions = ['(host-event)="onEvent(\$event)"'];
|
||||||
|
@ -32,12 +32,7 @@ import {
|
|||||||
DirectiveIndex,
|
DirectiveIndex,
|
||||||
PipeTransform,
|
PipeTransform,
|
||||||
PipeOnDestroy,
|
PipeOnDestroy,
|
||||||
CHECK_ALWAYS,
|
ChangeDetectionStrategy,
|
||||||
CHECK_ONCE,
|
|
||||||
CHECKED,
|
|
||||||
DETACHED,
|
|
||||||
ON_PUSH,
|
|
||||||
DEFAULT,
|
|
||||||
WrappedValue,
|
WrappedValue,
|
||||||
DynamicProtoChangeDetector,
|
DynamicProtoChangeDetector,
|
||||||
ChangeDetectorDefinition,
|
ChangeDetectorDefinition,
|
||||||
@ -673,26 +668,26 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('mode', () => {
|
describe('mode', () => {
|
||||||
it('should set the mode to CHECK_ALWAYS when the default change detection is used', () => {
|
it('should set the mode to CheckAlways when the default change detection is used', () => {
|
||||||
var cd = _createWithoutHydrate('emptyUsingDefaultStrategy').changeDetector;
|
var cd = _createWithoutHydrate('emptyUsingDefaultStrategy').changeDetector;
|
||||||
expect(cd.mode).toEqual(null);
|
expect(cd.mode).toEqual(null);
|
||||||
|
|
||||||
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
expect(cd.mode).toEqual(CHECK_ALWAYS);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the mode to CHECK_ONCE when the push change detection is used', () => {
|
it('should set the mode to CheckOnce when the push change detection is used', () => {
|
||||||
var cd = _createWithoutHydrate('emptyUsingOnPushStrategy').changeDetector;
|
var cd = _createWithoutHydrate('emptyUsingOnPushStrategy').changeDetector;
|
||||||
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not check a detached change detector', () => {
|
it('should not check a detached change detector', () => {
|
||||||
var val = _createChangeDetector('a', new TestData('value'));
|
var val = _createChangeDetector('a', new TestData('value'));
|
||||||
|
|
||||||
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
val.changeDetector.mode = DETACHED;
|
val.changeDetector.mode = ChangeDetectionStrategy.Detached;
|
||||||
val.changeDetector.detectChanges();
|
val.changeDetector.detectChanges();
|
||||||
|
|
||||||
expect(val.dispatcher.log).toEqual([]);
|
expect(val.dispatcher.log).toEqual([]);
|
||||||
@ -702,33 +697,33 @@ export function main() {
|
|||||||
var val = _createChangeDetector('a', new TestData('value'));
|
var val = _createChangeDetector('a', new TestData('value'));
|
||||||
|
|
||||||
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
val.changeDetector.mode = CHECKED;
|
val.changeDetector.mode = ChangeDetectionStrategy.Checked;
|
||||||
val.changeDetector.detectChanges();
|
val.changeDetector.detectChanges();
|
||||||
|
|
||||||
expect(val.dispatcher.log).toEqual([]);
|
expect(val.dispatcher.log).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change CHECK_ONCE to CHECKED', () => {
|
it('should change CheckOnce to Checked', () => {
|
||||||
var cd = _createChangeDetector('10').changeDetector;
|
var cd = _createChangeDetector('10').changeDetector;
|
||||||
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
cd.mode = CHECK_ONCE;
|
cd.mode = ChangeDetectionStrategy.CheckOnce;
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECKED);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change the CHECK_ALWAYS', () => {
|
it('should not change the CheckAlways', () => {
|
||||||
var cd = _createChangeDetector('10').changeDetector;
|
var cd = _createChangeDetector('10').changeDetector;
|
||||||
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
cd.mode = CHECK_ALWAYS;
|
cd.mode = ChangeDetectionStrategy.CheckAlways;
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ALWAYS);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('marking ON_PUSH detectors as CHECK_ONCE after an update', () => {
|
describe('marking OnPush detectors as CheckOnce after an update', () => {
|
||||||
var childDirectiveDetectorRegular;
|
var childDirectiveDetectorRegular;
|
||||||
var childDirectiveDetectorOnPush;
|
var childDirectiveDetectorOnPush;
|
||||||
var directives;
|
var directives;
|
||||||
@ -736,53 +731,53 @@ export function main() {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
childDirectiveDetectorRegular = _createWithoutHydrate('10').changeDetector;
|
childDirectiveDetectorRegular = _createWithoutHydrate('10').changeDetector;
|
||||||
childDirectiveDetectorRegular.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
childDirectiveDetectorRegular.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
childDirectiveDetectorRegular.mode = CHECK_ALWAYS;
|
childDirectiveDetectorRegular.mode = ChangeDetectionStrategy.CheckAlways;
|
||||||
|
|
||||||
childDirectiveDetectorOnPush =
|
childDirectiveDetectorOnPush =
|
||||||
_createWithoutHydrate('emptyUsingOnPushStrategy').changeDetector;
|
_createWithoutHydrate('emptyUsingOnPushStrategy').changeDetector;
|
||||||
childDirectiveDetectorOnPush.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
childDirectiveDetectorOnPush.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||||
childDirectiveDetectorOnPush.mode = CHECKED;
|
childDirectiveDetectorOnPush.mode = ChangeDetectionStrategy.Checked;
|
||||||
|
|
||||||
directives =
|
directives =
|
||||||
new FakeDirectives([new TestData(null), new TestData(null)],
|
new FakeDirectives([new TestData(null), new TestData(null)],
|
||||||
[childDirectiveDetectorRegular, childDirectiveDetectorOnPush]);
|
[childDirectiveDetectorRegular, childDirectiveDetectorOnPush]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the mode to CHECK_ONCE when a binding is updated', () => {
|
it('should set the mode to CheckOnce when a binding is updated', () => {
|
||||||
var parentDetector =
|
var parentDetector =
|
||||||
_createWithoutHydrate('onPushRecordsUsingDefaultStrategy').changeDetector;
|
_createWithoutHydrate('onPushRecordsUsingDefaultStrategy').changeDetector;
|
||||||
parentDetector.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
parentDetector.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||||
|
|
||||||
parentDetector.detectChanges();
|
parentDetector.detectChanges();
|
||||||
|
|
||||||
// making sure that we only change the status of ON_PUSH components
|
// making sure that we only change the status of OnPush components
|
||||||
expect(childDirectiveDetectorRegular.mode).toEqual(CHECK_ALWAYS);
|
expect(childDirectiveDetectorRegular.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||||
|
|
||||||
expect(childDirectiveDetectorOnPush.mode).toEqual(CHECK_ONCE);
|
expect(childDirectiveDetectorOnPush.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should mark ON_PUSH detectors as CHECK_ONCE after an event', () => {
|
it('should mark OnPush detectors as CheckOnce after an event', () => {
|
||||||
var cd = _createWithoutHydrate('onPushWithEvent').changeDetector;
|
var cd = _createWithoutHydrate('onPushWithEvent').changeDetector;
|
||||||
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||||
cd.mode = CHECKED;
|
cd.mode = ChangeDetectionStrategy.Checked;
|
||||||
|
|
||||||
cd.handleEvent("event", 0, null);
|
cd.handleEvent("event", 0, null);
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should mark ON_PUSH detectors as CHECK_ONCE after a host event', () => {
|
it('should mark OnPush detectors as CheckOnce after a host event', () => {
|
||||||
var cd = _createWithoutHydrate('onPushWithHostEvent').changeDetector;
|
var cd = _createWithoutHydrate('onPushWithHostEvent').changeDetector;
|
||||||
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||||
|
|
||||||
cd.handleEvent("host-event", 0, null);
|
cd.handleEvent("host-event", 0, null);
|
||||||
|
|
||||||
expect(childDirectiveDetectorOnPush.mode).toEqual(CHECK_ONCE);
|
expect(childDirectiveDetectorOnPush.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (IS_DART) {
|
if (IS_DART) {
|
||||||
describe('ON_PUSH_OBSERVE', () => {
|
describe('OnPushObserve', () => {
|
||||||
it('should mark ON_PUSH_OBSERVE detectors as CHECK_ONCE when an observable fires an event',
|
it('should mark OnPushObserve detectors as CheckOnce when an observable fires an event',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
var context = new TestDirective();
|
var context = new TestDirective();
|
||||||
context.a = createObservableModel();
|
context.a = createObservableModel();
|
||||||
@ -791,15 +786,15 @@ export function main() {
|
|||||||
cd.hydrate(context, null, directives, null);
|
cd.hydrate(context, null, directives, null);
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECKED);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||||
|
|
||||||
context.a.pushUpdate();
|
context.a.pushUpdate();
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should mark ON_PUSH_OBSERVE detectors as CHECK_ONCE when an observable context fires an event',
|
it('should mark OnPushObserve detectors as CheckOnce when an observable context fires an event',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
var context = createObservableModel();
|
var context = createObservableModel();
|
||||||
|
|
||||||
@ -807,15 +802,15 @@ export function main() {
|
|||||||
cd.hydrate(context, null, directives, null);
|
cd.hydrate(context, null, directives, null);
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECKED);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||||
|
|
||||||
context.pushUpdate();
|
context.pushUpdate();
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should mark ON_PUSH_OBSERVE detectors as CHECK_ONCE when an observable directive fires an event',
|
it('should mark OnPushObserve detectors as CheckOnce when an observable directive fires an event',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
var dir = createObservableModel();
|
var dir = createObservableModel();
|
||||||
var directives = new FakeDirectives([dir], []);
|
var directives = new FakeDirectives([dir], []);
|
||||||
@ -824,12 +819,12 @@ export function main() {
|
|||||||
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECKED);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||||
|
|
||||||
dir.pushUpdate();
|
dir.pushUpdate();
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should unsubscribe from an old observable when an object changes',
|
it('should unsubscribe from an old observable when an object changes',
|
||||||
@ -843,14 +838,14 @@ export function main() {
|
|||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
context.a = createObservableModel();
|
context.a = createObservableModel();
|
||||||
cd.mode = CHECK_ONCE;
|
cd.mode = ChangeDetectionStrategy.CheckOnce;
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
|
||||||
// Updating this model will not reenable the detector. This model is not longer
|
// Updating this model will not reenable the detector. This model is not longer
|
||||||
// used.
|
// used.
|
||||||
originalModel.pushUpdate();
|
originalModel.pushUpdate();
|
||||||
tick();
|
tick();
|
||||||
expect(cd.mode).toEqual(CHECKED);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should unsubscribe from observables when dehydrating', fakeAsync(() => {
|
it('should unsubscribe from observables when dehydrating', fakeAsync(() => {
|
||||||
@ -872,7 +867,7 @@ export function main() {
|
|||||||
// used.
|
// used.
|
||||||
originalModel.pushUpdate();
|
originalModel.pushUpdate();
|
||||||
tick();
|
tick();
|
||||||
expect(cd.mode).toEqual(CHECKED);
|
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -887,22 +882,22 @@ export function main() {
|
|||||||
return val.changeDetector;
|
return val.changeDetector;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should mark all checked detectors as CHECK_ONCE until reaching a detached one', () => {
|
it('should mark all checked detectors as CheckOnce until reaching a detached one', () => {
|
||||||
var root = changeDetector(CHECK_ALWAYS, null);
|
var root = changeDetector(ChangeDetectionStrategy.CheckAlways, null);
|
||||||
var disabled = changeDetector(DETACHED, root);
|
var disabled = changeDetector(ChangeDetectionStrategy.Detached, root);
|
||||||
var parent = changeDetector(CHECKED, disabled);
|
var parent = changeDetector(ChangeDetectionStrategy.Checked, disabled);
|
||||||
var checkAlwaysChild = changeDetector(CHECK_ALWAYS, parent);
|
var checkAlwaysChild = changeDetector(ChangeDetectionStrategy.CheckAlways, parent);
|
||||||
var checkOnceChild = changeDetector(CHECK_ONCE, checkAlwaysChild);
|
var checkOnceChild = changeDetector(ChangeDetectionStrategy.CheckOnce, checkAlwaysChild);
|
||||||
var checkedChild = changeDetector(CHECKED, checkOnceChild);
|
var checkedChild = changeDetector(ChangeDetectionStrategy.Checked, checkOnceChild);
|
||||||
|
|
||||||
checkedChild.markPathToRootAsCheckOnce();
|
checkedChild.markPathToRootAsCheckOnce();
|
||||||
|
|
||||||
expect(root.mode).toEqual(CHECK_ALWAYS);
|
expect(root.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||||
expect(disabled.mode).toEqual(DETACHED);
|
expect(disabled.mode).toEqual(ChangeDetectionStrategy.Detached);
|
||||||
expect(parent.mode).toEqual(CHECK_ONCE);
|
expect(parent.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
expect(checkAlwaysChild.mode).toEqual(CHECK_ALWAYS);
|
expect(checkAlwaysChild.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||||
expect(checkOnceChild.mode).toEqual(CHECK_ONCE);
|
expect(checkOnceChild.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
expect(checkedChild.mode).toEqual(CHECK_ONCE);
|
expect(checkedChild.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import 'package:angular2/test_lib.dart';
|
|||||||
import 'package:observe/observe.dart';
|
import 'package:observe/observe.dart';
|
||||||
import 'package:angular2/src/core/directives/observable_list_diff.dart';
|
import 'package:angular2/src/core/directives/observable_list_diff.dart';
|
||||||
import 'package:angular2/src/core/change_detection/differs/default_iterable_differ.dart';
|
import 'package:angular2/src/core/change_detection/differs/default_iterable_differ.dart';
|
||||||
|
import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||||
|
|
||||||
class MockException implements Error {
|
class MockException implements Error {
|
||||||
var message;
|
var message;
|
||||||
@ -281,7 +282,7 @@ class OnChangeComponent implements OnChange {
|
|||||||
|
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'component-with-observable-list',
|
selector: 'component-with-observable-list',
|
||||||
changeDetection: ON_PUSH,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
properties: const ['list'],
|
properties: const ['list'],
|
||||||
bindings: const [
|
bindings: const [
|
||||||
const Binding(IterableDiffers,
|
const Binding(IterableDiffers,
|
||||||
|
@ -58,7 +58,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
PipeTransform,
|
PipeTransform,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
ON_PUSH,
|
ChangeDetectionStrategy,
|
||||||
ChangeDetection,
|
ChangeDetection,
|
||||||
DynamicChangeDetection,
|
DynamicChangeDetection,
|
||||||
ChangeDetectorGenConfig
|
ChangeDetectorGenConfig
|
||||||
@ -635,7 +635,7 @@ export function main() {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("ON_PUSH components", () => {
|
describe("OnPush components", () => {
|
||||||
it("should use ChangeDetectorRef to manually request a check",
|
it("should use ChangeDetectorRef to manually request a check",
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter],
|
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
@ -1672,7 +1672,8 @@ class DirectiveWithTitleAndHostProperty {
|
|||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'push-cmp', properties: ['prop'], changeDetection: ON_PUSH})
|
@Component(
|
||||||
|
{selector: 'push-cmp', properties: ['prop'], changeDetection: ChangeDetectionStrategy.OnPush})
|
||||||
@View({template: '{{field}}'})
|
@View({template: '{{field}}'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class PushCmp {
|
class PushCmp {
|
||||||
@ -1687,7 +1688,11 @@ class PushCmp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'push-cmp-with-ref', properties: ['prop'], changeDetection: ON_PUSH})
|
@Component({
|
||||||
|
selector: 'push-cmp-with-ref',
|
||||||
|
properties: ['prop'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
@View({template: '{{field}}'})
|
@View({template: '{{field}}'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class PushCmpWithRef {
|
class PushCmpWithRef {
|
||||||
@ -1708,7 +1713,7 @@ class PushCmpWithRef {
|
|||||||
propagate() { this.ref.requestCheck(); }
|
propagate() { this.ref.requestCheck(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'push-cmp-with-async', changeDetection: ON_PUSH})
|
@Component({selector: 'push-cmp-with-async', changeDetection: ChangeDetectionStrategy.OnPush})
|
||||||
@View({template: '{{field | async}}'})
|
@View({template: '{{field | async}}'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class PushCmpWithAsyncPipe {
|
class PushCmpWithAsyncPipe {
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
|
||||||
import {RenderDirectiveMetadata} from 'angular2/src/core/render/api';
|
|
||||||
import {
|
|
||||||
directiveMetadataFromMap,
|
|
||||||
directiveMetadataToMap
|
|
||||||
} from 'angular2/src/core/render/dom/convert';
|
|
||||||
import {ddescribe, describe, expect, it} from 'angular2/test_lib';
|
|
||||||
|
|
||||||
export function main() {
|
|
||||||
describe('convert', () => {
|
|
||||||
it('directiveMetadataToMap', () => {
|
|
||||||
var someComponent = new RenderDirectiveMetadata({
|
|
||||||
compileChildren: false,
|
|
||||||
hostListeners: MapWrapper.createFromPairs([['LKey', 'LVal']]),
|
|
||||||
hostProperties: MapWrapper.createFromPairs([['PKey', 'PVal']]),
|
|
||||||
hostActions: MapWrapper.createFromPairs([['AcKey', 'AcVal']]),
|
|
||||||
hostAttributes: MapWrapper.createFromPairs([['AtKey', 'AtVal']]),
|
|
||||||
id: 'someComponent',
|
|
||||||
properties: ['propKey: propVal'],
|
|
||||||
readAttributes: ['read1', 'read2'],
|
|
||||||
selector: 'some-comp',
|
|
||||||
type: RenderDirectiveMetadata.COMPONENT_TYPE,
|
|
||||||
exportAs: 'aaa',
|
|
||||||
callOnDestroy: true,
|
|
||||||
callOnChange: true,
|
|
||||||
callOnCheck: true,
|
|
||||||
callOnInit: true,
|
|
||||||
callOnAllChangesDone: true,
|
|
||||||
events: ['onFoo', 'onBar'],
|
|
||||||
changeDetection: 'CHECK_ONCE'
|
|
||||||
});
|
|
||||||
var map = directiveMetadataToMap(someComponent);
|
|
||||||
expect(map.get('compileChildren')).toEqual(false);
|
|
||||||
expect(map.get('hostListeners')).toEqual(MapWrapper.createFromPairs([['LKey', 'LVal']]));
|
|
||||||
expect(map.get('hostProperties')).toEqual(MapWrapper.createFromPairs([['PKey', 'PVal']]));
|
|
||||||
expect(map.get('hostActions')).toEqual(MapWrapper.createFromPairs([['AcKey', 'AcVal']]));
|
|
||||||
expect(map.get('hostAttributes')).toEqual(MapWrapper.createFromPairs([['AtKey', 'AtVal']]));
|
|
||||||
expect(map.get('id')).toEqual('someComponent');
|
|
||||||
expect(map.get('properties')).toEqual(['propKey: propVal']);
|
|
||||||
expect(map.get('readAttributes')).toEqual(['read1', 'read2']);
|
|
||||||
expect(map.get('selector')).toEqual('some-comp');
|
|
||||||
expect(map.get('type')).toEqual(RenderDirectiveMetadata.COMPONENT_TYPE);
|
|
||||||
expect(map.get('callOnDestroy')).toEqual(true);
|
|
||||||
expect(map.get('callOnCheck')).toEqual(true);
|
|
||||||
expect(map.get('callOnChange')).toEqual(true);
|
|
||||||
expect(map.get('callOnInit')).toEqual(true);
|
|
||||||
expect(map.get('callOnAllChangesDone')).toEqual(true);
|
|
||||||
expect(map.get('exportAs')).toEqual('aaa');
|
|
||||||
expect(map.get('events')).toEqual(['onFoo', 'onBar']);
|
|
||||||
expect(map.get('changeDetection')).toEqual('CHECK_ONCE');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('mapToDirectiveMetadata', () => {
|
|
||||||
var map = MapWrapper.createFromPairs([
|
|
||||||
['compileChildren', false],
|
|
||||||
['hostProperties', MapWrapper.createFromPairs([['PKey', 'testVal']])],
|
|
||||||
['hostListeners', MapWrapper.createFromPairs([['LKey', 'testVal']])],
|
|
||||||
['hostActions', MapWrapper.createFromPairs([['AcKey', 'testVal']])],
|
|
||||||
['hostAttributes', MapWrapper.createFromPairs([['AtKey', 'testVal']])],
|
|
||||||
['id', 'testId'],
|
|
||||||
['properties', ['propKey: propVal']],
|
|
||||||
['readAttributes', ['readTest1', 'readTest2']],
|
|
||||||
['selector', 'testSelector'],
|
|
||||||
['type', RenderDirectiveMetadata.DIRECTIVE_TYPE],
|
|
||||||
['exportAs', 'aaa'],
|
|
||||||
['callOnDestroy', true],
|
|
||||||
['callOnCheck', true],
|
|
||||||
['callOnInit', true],
|
|
||||||
['callOnChange', true],
|
|
||||||
['callOnAllChangesDone', true],
|
|
||||||
['events', ['onFoo', 'onBar']],
|
|
||||||
['changeDetection', 'CHECK_ONCE']
|
|
||||||
]);
|
|
||||||
var meta = directiveMetadataFromMap(map);
|
|
||||||
expect(meta.compileChildren).toEqual(false);
|
|
||||||
expect(meta.hostProperties).toEqual(MapWrapper.createFromPairs([['PKey', 'testVal']]));
|
|
||||||
expect(meta.hostListeners).toEqual(MapWrapper.createFromPairs([['LKey', 'testVal']]));
|
|
||||||
expect(meta.hostActions).toEqual(MapWrapper.createFromPairs([['AcKey', 'testVal']]));
|
|
||||||
expect(meta.hostAttributes).toEqual(MapWrapper.createFromPairs([['AtKey', 'testVal']]));
|
|
||||||
expect(meta.id).toEqual('testId');
|
|
||||||
expect(meta.properties).toEqual(['propKey: propVal']);
|
|
||||||
expect(meta.readAttributes).toEqual(['readTest1', 'readTest2']);
|
|
||||||
expect(meta.selector).toEqual('testSelector');
|
|
||||||
expect(meta.type).toEqual(RenderDirectiveMetadata.DIRECTIVE_TYPE);
|
|
||||||
expect(meta.exportAs).toEqual('aaa');
|
|
||||||
expect(meta.callOnDestroy).toEqual(true);
|
|
||||||
expect(meta.callOnCheck).toEqual(true);
|
|
||||||
expect(meta.callOnInit).toEqual(true);
|
|
||||||
expect(meta.callOnChange).toEqual(true);
|
|
||||||
expect(meta.callOnAllChangesDone).toEqual(true);
|
|
||||||
expect(meta.events).toEqual(['onFoo', 'onBar']);
|
|
||||||
expect(meta.changeDetection).toEqual('CHECK_ONCE');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -15,8 +15,7 @@ import {
|
|||||||
ChangeDetectorGenConfig,
|
ChangeDetectorGenConfig,
|
||||||
BindingRecord,
|
BindingRecord,
|
||||||
DirectiveRecord,
|
DirectiveRecord,
|
||||||
DirectiveIndex,
|
DirectiveIndex
|
||||||
DEFAULT
|
|
||||||
} from 'angular2/src/core/change_detection/change_detection';
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import "package:angular2/src/core/facade/collection.dart"
|
|||||||
import "common.dart"
|
import "common.dart"
|
||||||
show Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST;
|
show Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST;
|
||||||
import "package:angular2/directives.dart" show NgFor;
|
import "package:angular2/directives.dart" show NgFor;
|
||||||
import "package:angular2/angular2.dart" show Component, Directive, View;
|
import "package:angular2/angular2.dart" show Component, Directive, View, ChangeDetectionStrategy;
|
||||||
|
|
||||||
class HasStyle {
|
class HasStyle {
|
||||||
int cellWidth;
|
int cellWidth;
|
||||||
@ -17,7 +17,7 @@ class HasStyle {
|
|||||||
@Component(
|
@Component(
|
||||||
selector: "company-name",
|
selector: "company-name",
|
||||||
properties: const ["width: cell-width", "company"],
|
properties: const ["width: cell-width", "company"],
|
||||||
changeDetection: "ON_PUSH_OBSERVE"
|
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||||
)
|
)
|
||||||
@View(
|
@View(
|
||||||
directives: const [],
|
directives: const [],
|
||||||
@ -29,7 +29,7 @@ class CompanyNameComponent extends HasStyle {
|
|||||||
@Component(
|
@Component(
|
||||||
selector: "opportunity-name",
|
selector: "opportunity-name",
|
||||||
properties: const ["width: cell-width", "opportunity"],
|
properties: const ["width: cell-width", "opportunity"],
|
||||||
changeDetection: "ON_PUSH_OBSERVE"
|
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||||
)
|
)
|
||||||
@View(
|
@View(
|
||||||
directives: const [],
|
directives: const [],
|
||||||
@ -41,7 +41,7 @@ class OpportunityNameComponent extends HasStyle {
|
|||||||
@Component(
|
@Component(
|
||||||
selector: "offering-name",
|
selector: "offering-name",
|
||||||
properties: const ["width: cell-width", "offering"],
|
properties: const ["width: cell-width", "offering"],
|
||||||
changeDetection: "ON_PUSH_OBSERVE"
|
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||||
)
|
)
|
||||||
@View(
|
@View(
|
||||||
directives: const [],
|
directives: const [],
|
||||||
@ -59,7 +59,7 @@ class Stage {
|
|||||||
@Component(
|
@Component(
|
||||||
selector: "stage-buttons",
|
selector: "stage-buttons",
|
||||||
properties: const ["width: cell-width", "offering"],
|
properties: const ["width: cell-width", "offering"],
|
||||||
changeDetection: "ON_PUSH_OBSERVE"
|
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||||
)
|
)
|
||||||
@View(directives: const [NgFor], template: '''
|
@View(directives: const [NgFor], template: '''
|
||||||
<div [style.width.px]="cellWidth">
|
<div [style.width.px]="cellWidth">
|
||||||
@ -103,7 +103,7 @@ class StageButtonsComponent extends HasStyle {
|
|||||||
@Component(
|
@Component(
|
||||||
selector: "account-cell",
|
selector: "account-cell",
|
||||||
properties: const ["width: cell-width", "account"],
|
properties: const ["width: cell-width", "account"],
|
||||||
changeDetection: "ON_PUSH_OBSERVE"
|
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||||
)
|
)
|
||||||
@View(directives: const [], template: '''
|
@View(directives: const [], template: '''
|
||||||
<div [style.width.px]="cellWidth">
|
<div [style.width.px]="cellWidth">
|
||||||
@ -117,7 +117,7 @@ class AccountCellComponent extends HasStyle {
|
|||||||
@Component(
|
@Component(
|
||||||
selector: "formatted-cell",
|
selector: "formatted-cell",
|
||||||
properties: const ["width: cell-width", "value"],
|
properties: const ["width: cell-width", "value"],
|
||||||
changeDetection: "ON_PUSH_OBSERVE"
|
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||||
)
|
)
|
||||||
@View(
|
@View(
|
||||||
directives: const [],
|
directives: const [],
|
||||||
|
@ -2,7 +2,7 @@ library benchmarks.src.naive_infinite_scroll.scroll_area;
|
|||||||
|
|
||||||
import "package:angular2/src/core/facade/collection.dart" show ListWrapper;
|
import "package:angular2/src/core/facade/collection.dart" show ListWrapper;
|
||||||
import "package:angular2/src/core/facade/math.dart" show Math;
|
import "package:angular2/src/core/facade/math.dart" show Math;
|
||||||
import "package:angular2/angular2.dart" show Component, Directive, View;
|
import "package:angular2/angular2.dart" show Component, Directive, View, ChangeDetectionStrategy;
|
||||||
import "common.dart"
|
import "common.dart"
|
||||||
show
|
show
|
||||||
Offering,
|
Offering,
|
||||||
@ -16,7 +16,7 @@ import "random_data.dart" show generateOfferings;
|
|||||||
import "scroll_item.dart" show ScrollItemComponent;
|
import "scroll_item.dart" show ScrollItemComponent;
|
||||||
import "package:angular2/directives.dart" show NgFor;
|
import "package:angular2/directives.dart" show NgFor;
|
||||||
|
|
||||||
@Component(selector: "scroll-area", changeDetection: "ON_PUSH_OBSERVE")
|
@Component(selector: "scroll-area", changeDetection: ChangeDetectionStrategy.OnPushObserve)
|
||||||
@View(directives: const [ScrollItemComponent, NgFor], template: '''
|
@View(directives: const [ScrollItemComponent, NgFor], template: '''
|
||||||
<div>
|
<div>
|
||||||
<div id="scrollDiv"
|
<div id="scrollDiv"
|
||||||
|
@ -8,7 +8,7 @@ import "cells.dart"
|
|||||||
StageButtonsComponent,
|
StageButtonsComponent,
|
||||||
AccountCellComponent,
|
AccountCellComponent,
|
||||||
FormattedCellComponent;
|
FormattedCellComponent;
|
||||||
import "package:angular2/angular2.dart" show Component, Directive, View;
|
import "package:angular2/angular2.dart" show Component, Directive, View, ChangeDetectionStrategy;
|
||||||
import "common.dart"
|
import "common.dart"
|
||||||
show
|
show
|
||||||
Offering,
|
Offering,
|
||||||
@ -25,7 +25,8 @@ import "common.dart"
|
|||||||
END_DATE_WIDTH,
|
END_DATE_WIDTH,
|
||||||
AAT_STATUS_WIDTH;
|
AAT_STATUS_WIDTH;
|
||||||
|
|
||||||
@Component(selector: "scroll-item", properties: const ["offering"], changeDetection: "ON_PUSH_OBSERVE")
|
@Component(selector: "scroll-item", properties: const ["offering"],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPushObserve)
|
||||||
@View(
|
@View(
|
||||||
directives: const [
|
directives: const [
|
||||||
CompanyNameComponent,
|
CompanyNameComponent,
|
||||||
|
71
modules_dart/transform/lib/src/transform/common/convert.dart
Normal file
71
modules_dart/transform/lib/src/transform/common/convert.dart
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
library angular2.transform.common.convert;
|
||||||
|
|
||||||
|
import "package:angular2/src/core/facade/collection.dart"
|
||||||
|
show ListWrapper, MapWrapper;
|
||||||
|
import "package:angular2/src/core/facade/lang.dart" show isPresent, isArray;
|
||||||
|
import "package:angular2/src/core/render/api.dart" show RenderDirectiveMetadata;
|
||||||
|
import "package:angular2/src/core/change_detection/change_detection.dart"
|
||||||
|
show ChangeDetectionStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a [DirectiveMetadata] to a map representation. This creates a copy,
|
||||||
|
* that is, subsequent changes to `meta` will not be mirrored in the map.
|
||||||
|
*/
|
||||||
|
Map<String, dynamic> directiveMetadataToMap(RenderDirectiveMetadata meta) {
|
||||||
|
return MapWrapper.createFromPairs([
|
||||||
|
["id", meta.id],
|
||||||
|
["selector", meta.selector],
|
||||||
|
["compileChildren", meta.compileChildren],
|
||||||
|
["hostProperties", _cloneIfPresent(meta.hostProperties)],
|
||||||
|
["hostListeners", _cloneIfPresent(meta.hostListeners)],
|
||||||
|
["hostAttributes", _cloneIfPresent(meta.hostAttributes)],
|
||||||
|
["properties", _cloneIfPresent(meta.properties)],
|
||||||
|
["readAttributes", _cloneIfPresent(meta.readAttributes)],
|
||||||
|
["type", meta.type],
|
||||||
|
["exportAs", meta.exportAs],
|
||||||
|
["callOnDestroy", meta.callOnDestroy],
|
||||||
|
["callOnCheck", meta.callOnCheck],
|
||||||
|
["callOnInit", meta.callOnInit],
|
||||||
|
["callOnChange", meta.callOnChange],
|
||||||
|
["callOnAllChangesDone", meta.callOnAllChangesDone],
|
||||||
|
["events", meta.events],
|
||||||
|
["changeDetection", meta.changeDetection == null ? null : meta.changeDetection.index],
|
||||||
|
["version", 1]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Converts a map representation of [DirectiveMetadata] into a
|
||||||
|
* [DirectiveMetadata] object. This creates a copy, that is, subsequent changes
|
||||||
|
* to `map` will not be mirrored in the [DirectiveMetadata] object.
|
||||||
|
*/
|
||||||
|
RenderDirectiveMetadata directiveMetadataFromMap(Map<String, dynamic> map) {
|
||||||
|
return new RenderDirectiveMetadata(
|
||||||
|
id: (map["id"] as String),
|
||||||
|
selector: (map["selector"] as String),
|
||||||
|
compileChildren: (map["compileChildren"] as bool),
|
||||||
|
hostProperties: (_cloneIfPresent(
|
||||||
|
map["hostProperties"]) as Map<String, String>),
|
||||||
|
hostListeners: (_cloneIfPresent(
|
||||||
|
map["hostListeners"]) as Map<String, String>),
|
||||||
|
hostAttributes: (_cloneIfPresent(
|
||||||
|
map["hostAttributes"]) as Map<String, String>),
|
||||||
|
properties: (_cloneIfPresent(map["properties"]) as List<String>),
|
||||||
|
readAttributes: (_cloneIfPresent(map["readAttributes"]) as List<String>),
|
||||||
|
type: (map["type"] as num),
|
||||||
|
exportAs: (map["exportAs"] as String),
|
||||||
|
callOnDestroy: (map["callOnDestroy"] as bool),
|
||||||
|
callOnCheck: (map["callOnCheck"] as bool),
|
||||||
|
callOnChange: (map["callOnChange"] as bool),
|
||||||
|
callOnInit: (map["callOnInit"] as bool),
|
||||||
|
callOnAllChangesDone: (map["callOnAllChangesDone"] as bool),
|
||||||
|
events: (_cloneIfPresent(map["events"]) as List<String>),
|
||||||
|
changeDetection: map["changeDetection"] == null ? null
|
||||||
|
: ChangeDetectionStrategy.values[map["changeDetection"] as int]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Clones the [List] or [Map] `o` if it is present.
|
||||||
|
*/
|
||||||
|
dynamic _cloneIfPresent(o) {
|
||||||
|
if (!isPresent(o)) return null;
|
||||||
|
return isArray(o) ? ListWrapper.clone(o) : MapWrapper.clone(o);
|
||||||
|
}
|
@ -3,6 +3,7 @@ library angular2.transform.common.directive_metadata_reader;
|
|||||||
import 'package:analyzer/analyzer.dart';
|
import 'package:analyzer/analyzer.dart';
|
||||||
import 'package:analyzer/src/generated/element.dart';
|
import 'package:analyzer/src/generated/element.dart';
|
||||||
import 'package:angular2/src/core/render/api.dart';
|
import 'package:angular2/src/core/render/api.dart';
|
||||||
|
import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||||
|
|
||||||
/// Reads [RenderDirectiveMetadata] from the `node`. `node` is expected to be an
|
/// Reads [RenderDirectiveMetadata] from the `node`. `node` is expected to be an
|
||||||
/// instance of [Annotation], [NodeList<Annotation>], ListLiteral, or
|
/// instance of [Annotation], [NodeList<Annotation>], ListLiteral, or
|
||||||
@ -63,7 +64,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||||||
bool _callOnCheck;
|
bool _callOnCheck;
|
||||||
bool _callOnInit;
|
bool _callOnInit;
|
||||||
bool _callOnAllChangesDone;
|
bool _callOnAllChangesDone;
|
||||||
String _changeDetection;
|
ChangeDetectionStrategy _changeDetection;
|
||||||
List<String> _events;
|
List<String> _events;
|
||||||
|
|
||||||
final ConstantEvaluator _evaluator = new ConstantEvaluator();
|
final ConstantEvaluator _evaluator = new ConstantEvaluator();
|
||||||
@ -283,6 +284,9 @@ class _DirectiveMetadataVisitor extends Object
|
|||||||
|
|
||||||
void _populateChangeDetection(Expression value) {
|
void _populateChangeDetection(Expression value) {
|
||||||
_checkMeta();
|
_checkMeta();
|
||||||
_changeDetection = _expressionToString(value, 'Directive#changeDetection');
|
_changeDetection = changeDetectionStrategies[value.toSource()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Map<String, ChangeDetectionStrategy> changeDetectionStrategies
|
||||||
|
= new Map.fromIterable(ChangeDetectionStrategy.values, key: (v) => v.toString());
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
library angular2.transform.common.ng_meta;
|
library angular2.transform.common.ng_meta;
|
||||||
|
|
||||||
import 'package:angular2/src/core/render/api.dart';
|
import 'package:angular2/src/core/render/api.dart';
|
||||||
import 'package:angular2/src/core/render/dom/convert.dart';
|
import 'convert.dart';
|
||||||
import 'logging.dart';
|
import 'logging.dart';
|
||||||
|
|
||||||
/// Metadata about directives and directive aliases.
|
/// Metadata about directives and directive aliases.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
library angular2.transform.template_compiler.change_detector_codegen;
|
library angular2.transform.template_compiler.change_detector_codegen;
|
||||||
|
|
||||||
|
import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||||
import 'package:angular2/src/core/change_detection/change_detection_util.dart';
|
import 'package:angular2/src/core/change_detection/change_detection_util.dart';
|
||||||
import 'package:angular2/src/core/change_detection/codegen_facade.dart';
|
import 'package:angular2/src/core/change_detection/codegen_facade.dart';
|
||||||
import 'package:angular2/src/core/change_detection/codegen_logic_util.dart';
|
import 'package:angular2/src/core/change_detection/codegen_logic_util.dart';
|
||||||
@ -75,7 +76,7 @@ class _CodegenState {
|
|||||||
/// The name of the generated change detector class. This is an implementation
|
/// The name of the generated change detector class. This is an implementation
|
||||||
/// detail and should not be visible to users.
|
/// detail and should not be visible to users.
|
||||||
final String _changeDetectorTypeName;
|
final String _changeDetectorTypeName;
|
||||||
final String _changeDetectionStrategy;
|
final ChangeDetectionStrategy _changeDetectionStrategy;
|
||||||
final List<DirectiveRecord> _directiveRecords;
|
final List<DirectiveRecord> _directiveRecords;
|
||||||
final List<ProtoRecord> _records;
|
final List<ProtoRecord> _records;
|
||||||
final List<EventBinding> _eventBindings;
|
final List<EventBinding> _eventBindings;
|
||||||
@ -84,6 +85,9 @@ class _CodegenState {
|
|||||||
final ChangeDetectorGenConfig _genConfig;
|
final ChangeDetectorGenConfig _genConfig;
|
||||||
final List<BindingTarget> _propertyBindingTargets;
|
final List<BindingTarget> _propertyBindingTargets;
|
||||||
|
|
||||||
|
String get _changeDetectionStrategyAsCode =>
|
||||||
|
_changeDetectionStrategy == null ? 'null' : '${_GEN_PREFIX}.${_changeDetectionStrategy}';
|
||||||
|
|
||||||
_CodegenState._(
|
_CodegenState._(
|
||||||
this._changeDetectorDefId,
|
this._changeDetectorDefId,
|
||||||
this._contextTypeName,
|
this._contextTypeName,
|
||||||
@ -129,7 +133,7 @@ class _CodegenState {
|
|||||||
dispatcher, ${_records.length},
|
dispatcher, ${_records.length},
|
||||||
${_changeDetectorTypeName}.gen_propertyBindingTargets,
|
${_changeDetectorTypeName}.gen_propertyBindingTargets,
|
||||||
${_changeDetectorTypeName}.gen_directiveIndices,
|
${_changeDetectorTypeName}.gen_directiveIndices,
|
||||||
${codify(_changeDetectionStrategy)}) {
|
${_changeDetectionStrategyAsCode}) {
|
||||||
dehydrateDirectives(false);
|
dehydrateDirectives(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
library angular2.test.transform.common.convert_spec;
|
||||||
|
|
||||||
|
import "package:angular2/src/core/facade/collection.dart" show MapWrapper;
|
||||||
|
import "package:angular2/src/core/render/api.dart" show RenderDirectiveMetadata;
|
||||||
|
import "package:angular2/src/transform/common/convert.dart"
|
||||||
|
show directiveMetadataFromMap, directiveMetadataToMap;
|
||||||
|
import "package:angular2/test_lib.dart" show ddescribe, describe, expect, it;
|
||||||
|
import "package:angular2/src/core/change_detection/change_detection.dart"
|
||||||
|
show ChangeDetectionStrategy;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
describe("convert", () {
|
||||||
|
it("directiveMetadataToMap", () {
|
||||||
|
var someComponent = new RenderDirectiveMetadata(
|
||||||
|
compileChildren: false,
|
||||||
|
hostListeners: MapWrapper.createFromPairs([["LKey", "LVal"]]),
|
||||||
|
hostProperties: MapWrapper.createFromPairs([["PKey", "PVal"]]),
|
||||||
|
hostAttributes: MapWrapper.createFromPairs([["AtKey", "AtVal"]]),
|
||||||
|
id: "someComponent",
|
||||||
|
properties: ["propKey: propVal"],
|
||||||
|
readAttributes: ["read1", "read2"],
|
||||||
|
selector: "some-comp",
|
||||||
|
type: RenderDirectiveMetadata.COMPONENT_TYPE,
|
||||||
|
exportAs: "aaa",
|
||||||
|
callOnDestroy: true,
|
||||||
|
callOnChange: true,
|
||||||
|
callOnCheck: true,
|
||||||
|
callOnInit: true,
|
||||||
|
callOnAllChangesDone: true,
|
||||||
|
events: ["onFoo", "onBar"],
|
||||||
|
changeDetection: ChangeDetectionStrategy.CheckOnce);
|
||||||
|
var map = directiveMetadataToMap(someComponent);
|
||||||
|
expect(map["compileChildren"]).toEqual(false);
|
||||||
|
expect(map["hostListeners"])
|
||||||
|
.toEqual(MapWrapper.createFromPairs([["LKey", "LVal"]]));
|
||||||
|
expect(map["hostProperties"])
|
||||||
|
.toEqual(MapWrapper.createFromPairs([["PKey", "PVal"]]));
|
||||||
|
expect(map["hostAttributes"])
|
||||||
|
.toEqual(MapWrapper.createFromPairs([["AtKey", "AtVal"]]));
|
||||||
|
expect(map["id"]).toEqual("someComponent");
|
||||||
|
expect(map["properties"]).toEqual(["propKey: propVal"]);
|
||||||
|
expect(map["readAttributes"]).toEqual(["read1", "read2"]);
|
||||||
|
expect(map["selector"]).toEqual("some-comp");
|
||||||
|
expect(map["type"]).toEqual(RenderDirectiveMetadata.COMPONENT_TYPE);
|
||||||
|
expect(map["callOnDestroy"]).toEqual(true);
|
||||||
|
expect(map["callOnCheck"]).toEqual(true);
|
||||||
|
expect(map["callOnChange"]).toEqual(true);
|
||||||
|
expect(map["callOnInit"]).toEqual(true);
|
||||||
|
expect(map["callOnAllChangesDone"]).toEqual(true);
|
||||||
|
expect(map["exportAs"]).toEqual("aaa");
|
||||||
|
expect(map["events"]).toEqual(["onFoo", "onBar"]);
|
||||||
|
expect(map["changeDetection"]).toEqual(ChangeDetectionStrategy.CheckOnce.index);
|
||||||
|
});
|
||||||
|
it("mapToDirectiveMetadata", () {
|
||||||
|
var map = MapWrapper.createFromPairs([
|
||||||
|
["compileChildren", false],
|
||||||
|
["hostProperties", MapWrapper.createFromPairs([["PKey", "testVal"]])],
|
||||||
|
["hostListeners", MapWrapper.createFromPairs([["LKey", "testVal"]])],
|
||||||
|
["hostAttributes", MapWrapper.createFromPairs([["AtKey", "testVal"]])],
|
||||||
|
["id", "testId"],
|
||||||
|
["properties", ["propKey: propVal"]],
|
||||||
|
["readAttributes", ["readTest1", "readTest2"]],
|
||||||
|
["selector", "testSelector"],
|
||||||
|
["type", RenderDirectiveMetadata.DIRECTIVE_TYPE],
|
||||||
|
["exportAs", "aaa"],
|
||||||
|
["callOnDestroy", true],
|
||||||
|
["callOnCheck", true],
|
||||||
|
["callOnInit", true],
|
||||||
|
["callOnChange", true],
|
||||||
|
["callOnAllChangesDone", true],
|
||||||
|
["events", ["onFoo", "onBar"]],
|
||||||
|
["changeDetection", ChangeDetectionStrategy.CheckOnce.index]
|
||||||
|
]);
|
||||||
|
var meta = directiveMetadataFromMap(map);
|
||||||
|
expect(meta.compileChildren).toEqual(false);
|
||||||
|
expect(meta.hostProperties)
|
||||||
|
.toEqual(MapWrapper.createFromPairs([["PKey", "testVal"]]));
|
||||||
|
expect(meta.hostListeners)
|
||||||
|
.toEqual(MapWrapper.createFromPairs([["LKey", "testVal"]]));
|
||||||
|
expect(meta.hostAttributes)
|
||||||
|
.toEqual(MapWrapper.createFromPairs([["AtKey", "testVal"]]));
|
||||||
|
expect(meta.id).toEqual("testId");
|
||||||
|
expect(meta.properties).toEqual(["propKey: propVal"]);
|
||||||
|
expect(meta.readAttributes).toEqual(["readTest1", "readTest2"]);
|
||||||
|
expect(meta.selector).toEqual("testSelector");
|
||||||
|
expect(meta.type).toEqual(RenderDirectiveMetadata.DIRECTIVE_TYPE);
|
||||||
|
expect(meta.exportAs).toEqual("aaa");
|
||||||
|
expect(meta.callOnDestroy).toEqual(true);
|
||||||
|
expect(meta.callOnCheck).toEqual(true);
|
||||||
|
expect(meta.callOnInit).toEqual(true);
|
||||||
|
expect(meta.callOnChange).toEqual(true);
|
||||||
|
expect(meta.callOnAllChangesDone).toEqual(true);
|
||||||
|
expect(meta.events).toEqual(["onFoo", "onBar"]);
|
||||||
|
expect(meta.changeDetection).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -2,7 +2,8 @@ library angular2.test.transform.directive_metadata_extractor.all_tests;
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:angular2/src/core/render/api.dart';
|
import 'package:angular2/src/core/render/api.dart';
|
||||||
import 'package:angular2/src/core/render/dom/convert.dart';
|
import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||||
|
import 'package:angular2/src/transform/common/convert.dart';
|
||||||
import 'package:angular2/src/transform/common/directive_metadata_reader.dart';
|
import 'package:angular2/src/transform/common/directive_metadata_reader.dart';
|
||||||
import 'package:angular2/src/transform/common/logging.dart';
|
import 'package:angular2/src/transform/common/logging.dart';
|
||||||
import 'package:angular2/src/transform/common/ng_deps.dart';
|
import 'package:angular2/src/transform/common/ng_deps.dart';
|
||||||
@ -122,7 +123,7 @@ void allTests() {
|
|||||||
it('should parse changeDetection.', () async {
|
it('should parse changeDetection.', () async {
|
||||||
var metadata = await readMetadata('directive_metadata_extractor/'
|
var metadata = await readMetadata('directive_metadata_extractor/'
|
||||||
'directive_metadata_files/changeDetection.ng_deps.dart');
|
'directive_metadata_files/changeDetection.ng_deps.dart');
|
||||||
expect(metadata.changeDetection).toEqual('CHECK_ONCE');
|
expect(metadata.changeDetection).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when a class is annotated with multiple Directives.',
|
it('should fail when a class is annotated with multiple Directives.',
|
||||||
|
@ -2,7 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
|
|||||||
|
|
||||||
import 'hello.dart';
|
import 'hello.dart';
|
||||||
import 'package:angular2/angular2.dart'
|
import 'package:angular2/angular2.dart'
|
||||||
show Component, Directive, View, NgElement, LifecycleEvent;
|
show Component, Directive, View, NgElement, LifecycleEvent, ChangeDetectionStrategy;
|
||||||
|
|
||||||
var _visited = false;
|
var _visited = false;
|
||||||
void initReflector(reflector) {
|
void initReflector(reflector) {
|
||||||
@ -12,7 +12,7 @@ void initReflector(reflector) {
|
|||||||
..registerType(
|
..registerType(
|
||||||
HelloCmp,
|
HelloCmp,
|
||||||
new ReflectionInfo(
|
new ReflectionInfo(
|
||||||
const [const Component(changeDetection: 'CHECK_ONCE')],
|
const [const Component(changeDetection: ChangeDetectionStrategy.CheckOnce)],
|
||||||
const [const []],
|
const [const []],
|
||||||
() => new HelloCmp()));
|
() => new HelloCmp()));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user