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:
@ -12,10 +12,9 @@ import {
|
||||
} from './exceptions';
|
||||
import {BindingTarget} from './binding_record';
|
||||
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 {isObservable} from './observable_facade';
|
||||
import {ON_PUSH_OBSERVE} from './constants';
|
||||
|
||||
|
||||
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
|
||||
@ -36,7 +35,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
alreadyChecked: any = false;
|
||||
context: T;
|
||||
locals: Locals = null;
|
||||
mode: string = null;
|
||||
mode: ChangeDetectionStrategy = null;
|
||||
pipes: Pipes = null;
|
||||
propertyBindingIndex: number;
|
||||
|
||||
@ -46,7 +45,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
|
||||
constructor(public id: string, public dispatcher: ChangeDispatcher,
|
||||
public numberOfPropertyProtoRecords: number, public bindingTargets: BindingTarget[],
|
||||
public directiveIndices: DirectiveIndex[], public strategy: string) {
|
||||
public directiveIndices: DirectiveIndex[], public strategy: ChangeDetectionStrategy) {
|
||||
this.ref = new ChangeDetectorRef(this);
|
||||
}
|
||||
|
||||
@ -79,14 +78,16 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
checkNoChanges(): void { throw new BaseException("Not implemented"); }
|
||||
|
||||
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;
|
||||
var s = _scope_check(this.id, throwOnChange);
|
||||
this.detectChangesInRecords(throwOnChange);
|
||||
this._detectChangesInLightDomChildren(throwOnChange);
|
||||
if (throwOnChange === false) this.callOnAllChangesDone();
|
||||
this._detectChangesInShadowDomChildren(throwOnChange);
|
||||
if (StringWrapper.equals(this.mode, CHECK_ONCE)) this.mode = CHECKED;
|
||||
if (this.mode === ChangeDetectionStrategy.CheckOnce)
|
||||
this.mode = ChangeDetectionStrategy.Checked;
|
||||
wtfLeave(s);
|
||||
}
|
||||
|
||||
@ -121,7 +122,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
this.mode = ChangeDetectionUtil.changeDetectionMode(this.strategy);
|
||||
this.context = context;
|
||||
|
||||
if (StringWrapper.equals(this.strategy, ON_PUSH_OBSERVE)) {
|
||||
if (this.strategy === ChangeDetectionStrategy.OnPushObserve) {
|
||||
this.observeComponent(context);
|
||||
}
|
||||
|
||||
@ -140,7 +141,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
this.dehydrateDirectives(true);
|
||||
|
||||
// This is an experimental feature. Works only in Dart.
|
||||
if (StringWrapper.equals(this.strategy, ON_PUSH_OBSERVE)) {
|
||||
if (this.strategy === ChangeDetectionStrategy.OnPushObserve) {
|
||||
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 {
|
||||
var c: ChangeDetector = this;
|
||||
while (isPresent(c) && !StringWrapper.equals(c.mode, DETACHED)) {
|
||||
if (StringWrapper.equals(c.mode, CHECKED)) c.mode = CHECK_ONCE;
|
||||
while (isPresent(c) && c.mode !== ChangeDetectionStrategy.Detached) {
|
||||
if (c.mode === ChangeDetectionStrategy.Checked) c.mode = ChangeDetectionStrategy.CheckOnce;
|
||||
c = c.parent;
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ export {
|
||||
DebugContext,
|
||||
ChangeDetectorGenConfig
|
||||
} 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 {BindingRecord, BindingTarget} from './binding_record';
|
||||
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||
|
@ -12,6 +12,8 @@ import {codify} from './codegen_facade';
|
||||
import {EventBinding} from './event_binding';
|
||||
import {BindingTarget} from './binding_record';
|
||||
import {ChangeDetectorGenConfig} from './interfaces';
|
||||
import {ChangeDetectionStrategy} from './constants';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -33,7 +35,7 @@ export class ChangeDetectorJITGenerator {
|
||||
_names: CodegenNameUtil;
|
||||
_typeName: string;
|
||||
|
||||
constructor(private id: string, private changeDetectionStrategy: string,
|
||||
constructor(private id: string, private changeDetectionStrategy: ChangeDetectionStrategy,
|
||||
private records: List<ProtoRecord>, private propertyBindingTargets: BindingTarget[],
|
||||
private eventBindings: EventBinding[], private directiveRecords: List<any>,
|
||||
private genConfig: ChangeDetectorGenConfig) {
|
||||
|
@ -8,13 +8,7 @@ import {
|
||||
} from 'angular2/src/core/facade/lang';
|
||||
import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {ProtoRecord} from './proto_record';
|
||||
import {
|
||||
CHECK_ALWAYS,
|
||||
CHECK_ONCE,
|
||||
CHECKED,
|
||||
DETACHED,
|
||||
isDefaultChangeDetectionStrategy
|
||||
} from './constants';
|
||||
import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants';
|
||||
import {implementsOnDestroy} from './pipe_lifecycle_reflector';
|
||||
import {BindingTarget} from './binding_record';
|
||||
import {DirectiveIndex} from './directive_record';
|
||||
@ -180,8 +174,9 @@ export class ChangeDetectionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static changeDetectionMode(strategy: string): string {
|
||||
return isDefaultChangeDetectionStrategy(strategy) ? CHECK_ALWAYS : CHECK_ONCE;
|
||||
static changeDetectionMode(strategy: ChangeDetectionStrategy): ChangeDetectionStrategy {
|
||||
return isDefaultChangeDetectionStrategy(strategy) ? ChangeDetectionStrategy.CheckAlways :
|
||||
ChangeDetectionStrategy.CheckOnce;
|
||||
}
|
||||
|
||||
static simpleChange(previousValue: any, currentValue: any): SimpleChange {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {ChangeDetector} from './interfaces';
|
||||
import {CHECK_ONCE, DETACHED, CHECK_ALWAYS} from './constants';
|
||||
import {ChangeDetectionStrategy} from './constants';
|
||||
|
||||
/**
|
||||
* Controls change detection.
|
||||
@ -14,7 +14,7 @@ export class ChangeDetectorRef {
|
||||
constructor(private _cd: ChangeDetector) {}
|
||||
|
||||
/**
|
||||
* Request to check all ON_PUSH ancestors.
|
||||
* Request to check all OnPush ancestors.
|
||||
*/
|
||||
requestCheck(): void { this._cd.markPathToRootAsCheckOnce(); }
|
||||
|
||||
@ -23,7 +23,7 @@ export class ChangeDetectorRef {
|
||||
*
|
||||
* 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.
|
||||
@ -33,7 +33,7 @@ export class ChangeDetectorRef {
|
||||
* next change detection run.
|
||||
*/
|
||||
reattach(): void {
|
||||
this._cd.mode = CHECK_ALWAYS;
|
||||
this._cd.mode = ChangeDetectionStrategy.CheckAlways;
|
||||
this.requestCheck();
|
||||
}
|
||||
}
|
||||
|
@ -11,14 +11,14 @@ import {codify, combineGeneratedStrings, rawString} from './codegen_facade';
|
||||
import {ProtoRecord, RecordType} from './proto_record';
|
||||
import {BindingTarget} from './binding_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.
|
||||
*/
|
||||
export class CodegenLogicUtil {
|
||||
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
|
||||
@ -119,7 +119,7 @@ export class CodegenLogicUtil {
|
||||
|
||||
_observe(exp: string, rec: ProtoRecord): string {
|
||||
// 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})`;
|
||||
} else {
|
||||
return exp;
|
||||
@ -165,7 +165,7 @@ export class CodegenLogicUtil {
|
||||
|
||||
private _genReadDirective(index: number) {
|
||||
// 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})`;
|
||||
} else {
|
||||
return `this.getDirectiveFor(directives, ${index})`;
|
||||
|
@ -1,46 +1,49 @@
|
||||
// TODO:vsavkin Use enums after switching to TypeScript
|
||||
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
||||
|
||||
/**
|
||||
* CHECK_ONCE means that after calling detectChanges the mode of the change detector
|
||||
* will become CHECKED.
|
||||
*/
|
||||
export const CHECK_ONCE: string = "CHECK_ONCE";
|
||||
export enum ChangeDetectionStrategy {
|
||||
/**
|
||||
* `CheckedOnce` means that after calling detectChanges the mode of the change detector
|
||||
* will become `Checked`.
|
||||
*/
|
||||
CheckOnce,
|
||||
|
||||
/**
|
||||
* CHECKED means that the change detector should be skipped until its mode changes to
|
||||
* CHECK_ONCE or CHECK_ALWAYS.
|
||||
*/
|
||||
export const CHECKED: string = "CHECKED";
|
||||
/**
|
||||
* `Checked` means that the change detector should be skipped until its mode changes to
|
||||
* `CheckOnce`.
|
||||
*/
|
||||
Checked,
|
||||
|
||||
/**
|
||||
* CHECK_ALWAYS means that after calling detectChanges the mode of the change detector
|
||||
* will remain CHECK_ALWAYS.
|
||||
*/
|
||||
export const CHECK_ALWAYS: string = "ALWAYS_CHECK";
|
||||
/**
|
||||
* `CheckAlways` means that after calling detectChanges the mode of the change detector
|
||||
* will remain `CheckAlways`.
|
||||
*/
|
||||
CheckAlways,
|
||||
|
||||
/**
|
||||
* DETACHED means that the change detector sub tree is not a part of the main tree and
|
||||
* should be skipped.
|
||||
*/
|
||||
export const DETACHED: string = "DETACHED";
|
||||
/**
|
||||
* `Detached` means that the change detector sub tree is not a part of the main tree and
|
||||
* should be skipped.
|
||||
*/
|
||||
Detached,
|
||||
|
||||
/**
|
||||
* ON_PUSH means that the change detector's mode will be set to CHECK_ONCE during hydration.
|
||||
*/
|
||||
export const ON_PUSH: string = "ON_PUSH";
|
||||
/**
|
||||
* `OnPush` means that the change detector's mode will be set to `CheckOnce` during hydration.
|
||||
*/
|
||||
OnPush,
|
||||
|
||||
/**
|
||||
* DEFAULT means that the change detector's mode will be set to CHECK_ALWAYS during hydration.
|
||||
*/
|
||||
export const DEFAULT: string = "DEFAULT";
|
||||
/**
|
||||
* `Default` means that the change detector's mode will be set to `CheckAlways` during hydration.
|
||||
*/
|
||||
Default,
|
||||
|
||||
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: string): boolean {
|
||||
return isBlank(changeDetectionStrategy) || StringWrapper.equals(changeDetectionStrategy, DEFAULT);
|
||||
/**
|
||||
* This is an experimental feature. Works only in Dart.
|
||||
*/
|
||||
OnPushObserve
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is an experimental feature. Works only in Dart.
|
||||
*/
|
||||
export const ON_PUSH_OBSERVE = "ON_PUSH_OBSERVE";
|
||||
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: ChangeDetectionStrategy):
|
||||
boolean {
|
||||
return isBlank(changeDetectionStrategy) ||
|
||||
changeDetectionStrategy === ChangeDetectionStrategy.Default;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
||||
import {isDefaultChangeDetectionStrategy} from './constants';
|
||||
import {isDefaultChangeDetectionStrategy, ChangeDetectionStrategy} from './constants';
|
||||
|
||||
export class DirectiveIndex {
|
||||
constructor(public elementIndex: number, public directiveIndex: number) {}
|
||||
@ -13,7 +13,7 @@ export class DirectiveRecord {
|
||||
callOnChange: boolean;
|
||||
callOnCheck: boolean;
|
||||
callOnInit: boolean;
|
||||
changeDetection: string;
|
||||
changeDetection: ChangeDetectionStrategy;
|
||||
|
||||
constructor({directiveIndex, callOnAllChangesDone, callOnChange, callOnCheck, callOnInit,
|
||||
changeDetection}: {
|
||||
@ -22,7 +22,7 @@ export class DirectiveRecord {
|
||||
callOnChange?: boolean,
|
||||
callOnCheck?: boolean,
|
||||
callOnInit?: boolean,
|
||||
changeDetection?: string
|
||||
changeDetection?: ChangeDetectionStrategy
|
||||
} = {}) {
|
||||
this.directiveIndex = directiveIndex;
|
||||
this.callOnAllChangesDone = normalizeBool(callOnAllChangesDone);
|
||||
@ -35,4 +35,4 @@ export class DirectiveRecord {
|
||||
isDefaultChangeDetection(): boolean {
|
||||
return isDefaultChangeDetectionStrategy(this.changeDetection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import {DirectiveRecord, DirectiveIndex} from './directive_record';
|
||||
import {Locals} from './parser/locals';
|
||||
import {ChangeDetectorGenConfig} from './interfaces';
|
||||
import {ChangeDetectionUtil, SimpleChange} from './change_detection_util';
|
||||
import {ON_PUSH_OBSERVE} from './constants';
|
||||
import {ChangeDetectionStrategy} from './constants';
|
||||
import {ProtoRecord, RecordType} from './proto_record';
|
||||
|
||||
export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
@ -26,7 +26,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
|
||||
constructor(id: string, dispatcher: any, numberOfPropertyProtoRecords: number,
|
||||
propertyBindingTargets: BindingTarget[], directiveIndices: DirectiveIndex[],
|
||||
strategy: string, private records: ProtoRecord[],
|
||||
strategy: ChangeDetectionStrategy, private records: ProtoRecord[],
|
||||
private eventBindings: EventBinding[], private directiveRecords: DirectiveRecord[],
|
||||
private genConfig: ChangeDetectorGenConfig) {
|
||||
super(id, dispatcher, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices,
|
||||
@ -88,7 +88,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
this.values[0] = this.context;
|
||||
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) {
|
||||
var index = this.directiveIndices[i];
|
||||
super.observeDirective(directives.getDirectiveFor(index), i);
|
||||
@ -219,7 +219,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import {CONST} from 'angular2/src/core/facade/lang';
|
||||
import {Locals} from './parser/locals';
|
||||
import {BindingTarget, BindingRecord} from './binding_record';
|
||||
import {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||
import {ChangeDetectionStrategy} from './constants';
|
||||
import {ChangeDetectorRef} from './change_detector_ref';
|
||||
|
||||
/**
|
||||
@ -55,7 +56,7 @@ export interface ChangeDispatcher {
|
||||
|
||||
export interface ChangeDetector {
|
||||
parent: ChangeDetector;
|
||||
mode: string;
|
||||
mode: ChangeDetectionStrategy;
|
||||
ref: ChangeDetectorRef;
|
||||
|
||||
addChild(cd: ChangeDetector): void;
|
||||
@ -80,8 +81,8 @@ export class ChangeDetectorGenConfig {
|
||||
}
|
||||
|
||||
export class ChangeDetectorDefinition {
|
||||
constructor(public id: string, public strategy: string, public variableNames: List<string>,
|
||||
public bindingRecords: BindingRecord[], public eventRecords: BindingRecord[],
|
||||
public directiveRecords: DirectiveRecord[],
|
||||
constructor(public id: string, public strategy: ChangeDetectionStrategy,
|
||||
public variableNames: List<string>, public bindingRecords: BindingRecord[],
|
||||
public eventRecords: BindingRecord[], public directiveRecords: DirectiveRecord[],
|
||||
public genConfig: ChangeDetectorGenConfig) {}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ export 'dart:core' show List;
|
||||
export 'package:angular2/src/core/change_detection/abstract_change_detector.dart'
|
||||
show AbstractChangeDetector;
|
||||
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'
|
||||
show DirectiveIndex, DirectiveRecord;
|
||||
export 'package:angular2/src/core/change_detection/interfaces.dart'
|
||||
|
Reference in New Issue
Block a user