feat(core): split ChangeDetectorStrategy into ChangeDetectionStrategy and ChangeDetectorStatus

This commit is contained in:
vsavkin
2016-06-27 20:00:30 -07:00
parent 797914e948
commit e12b1277df
13 changed files with 91 additions and 109 deletions

View File

@ -14,7 +14,7 @@ import {KeyValueDifferFactory, KeyValueDiffers} from './differs/keyvalue_differs
export {SimpleChanges} from '../metadata/lifecycle_hooks';
export {SimpleChange, ValueUnwrapper, WrappedValue, devModeEqual, looseIdentical, uninitialized} from './change_detection_util';
export {ChangeDetectorRef} from './change_detector_ref';
export {CHANGE_DETECTION_STRATEGY_VALUES, CHANGE_DETECTOR_STATE_VALUES, ChangeDetectionStrategy, ChangeDetectorState, isDefaultChangeDetectionStrategy} from './constants';
export {CHANGE_DETECTION_STRATEGY_VALUES, ChangeDetectionStrategy, ChangeDetectorStatus, isDefaultChangeDetectionStrategy} from './constants';
export {CollectionChangeRecord, DefaultIterableDifferFactory} from './differs/default_iterable_differ';
export {DefaultIterableDiffer} from './differs/default_iterable_differ';
export {DefaultKeyValueDifferFactory, KeyValueChangeRecord} from './differs/default_keyvalue_differ';
@ -23,6 +23,7 @@ export {KeyValueDiffer, KeyValueDifferFactory, KeyValueDiffers} from './differs/
export {PipeTransform} from './pipe_transform';
/**
* Structural diffing for `Object`s and `Map`s.
*/

View File

@ -8,37 +8,27 @@
import {isBlank} from '../facade/lang';
/**
* Describes the current state of the change detector.
*/
export enum ChangeDetectorState {
/**
* `NeverChecked` means that the change detector has not been checked yet, and
* initialization methods should be called during detection.
*/
NeverChecked,
/**
* `CheckedBefore` means that the change detector has successfully completed at least
* one detection previously.
*/
CheckedBefore,
/**
* `Errored` means that the change detector encountered an error checking a binding
* or calling a directive lifecycle method and is now in an inconsistent state. Change
* detectors in this state will no longer detect changes.
*/
Errored,
}
/**
* Describes within the change detector which strategy will be used the next time change
* detection is triggered.
* @stable
*/
export enum ChangeDetectionStrategy {
/**
* `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 `CheckAlways` during hydration.
*/
Default,
}
/**
* Describes the status of the detector.
*/
export enum ChangeDetectorStatus {
/**
* `CheckedOnce` means that after calling detectChanges the mode of the change detector
* will become `Checked`.
@ -64,35 +54,35 @@ export enum ChangeDetectionStrategy {
Detached,
/**
* `OnPush` means that the change detector's mode will be set to `CheckOnce` during hydration.
* `Errored` means that the change detector encountered an error checking a binding
* or calling a directive lifecycle method and is now in an inconsistent state. Change
* detectors in this state will no longer detect changes.
*/
OnPush,
Errored,
/**
* `Default` means that the change detector's mode will be set to `CheckAlways` during hydration.
* `Destroyed` means that the change detector is destroyed.
*/
Default,
Destroyed,
}
/**
* List of possible {@link ChangeDetectionStrategy} values.
*/
export var CHANGE_DETECTION_STRATEGY_VALUES = [
ChangeDetectionStrategy.CheckOnce,
ChangeDetectionStrategy.Checked,
ChangeDetectionStrategy.CheckAlways,
ChangeDetectionStrategy.Detached,
ChangeDetectionStrategy.OnPush,
ChangeDetectionStrategy.Default,
];
/**
* List of possible {@link ChangeDetectorState} values.
* List of possible {@link ChangeDetectorStatus} values.
*/
export var CHANGE_DETECTOR_STATE_VALUES = [
ChangeDetectorState.NeverChecked,
ChangeDetectorState.CheckedBefore,
ChangeDetectorState.Errored,
export var CHANGE_DETECTOR_STATUS_VALUES = [
ChangeDetectorStatus.CheckOnce,
ChangeDetectorStatus.Checked,
ChangeDetectorStatus.CheckAlways,
ChangeDetectorStatus.Detached,
ChangeDetectorStatus.Errored,
ChangeDetectorStatus.Destroyed,
];
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: ChangeDetectionStrategy):

View File

@ -16,7 +16,7 @@ import {ViewRef_} from './view_ref';
import {ViewType} from './view_type';
import {ViewUtils, arrayLooseIdentical, ensureSlotCount, flattenNestedViewRenderNodes, mapLooseIdentical} from './view_utils';
import {ChangeDetectorRef, ChangeDetectionStrategy, ChangeDetectorState,} from '../change_detection/change_detection';
import {ChangeDetectorRef, ChangeDetectionStrategy, ChangeDetectorStatus,} from '../change_detection/change_detection';
import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile';
import {ExpressionChangedAfterItHasBeenCheckedException, ViewDestroyedException, ViewWrappedException} from './exceptions';
import {StaticNodeDebugInfo, DebugContext} from './debug_context';
@ -47,14 +47,10 @@ export abstract class AppView<T> {
viewChildren: AppView<any>[] = [];
viewContainerElement: AppElement = null;
// The names of the below fields must be kept in sync with codegen_name_util.ts or
// change detection will fail.
cdState: ChangeDetectorState = ChangeDetectorState.NeverChecked;
numberOfChecks: number = 0;
projectableNodes: Array<any|any[]>;
destroyed: boolean = false;
renderer: Renderer;
private _hasExternalHostElement: boolean;
@ -66,7 +62,7 @@ export abstract class AppView<T> {
constructor(
public clazz: any, public componentType: RenderComponentType, public type: ViewType,
public viewUtils: ViewUtils, public parentInjector: Injector,
public declarationAppElement: AppElement, public cdMode: ChangeDetectionStrategy) {
public declarationAppElement: AppElement, public cdMode: ChangeDetectorStatus) {
this.ref = new ViewRef_(this);
if (type === ViewType.COMPONENT || type === ViewType.HOST) {
this.renderer = viewUtils.renderComponent(componentType);
@ -75,6 +71,8 @@ export abstract class AppView<T> {
}
}
get destroyed(): boolean { return this.cdMode === ChangeDetectorStatus.Destroyed; }
cancelActiveAnimation(element: any, animationName: string, removeAllAnimations: boolean = false) {
if (removeAllAnimations) {
this.activeAnimationPlayers.findAllPlayersByElement(element).forEach(
@ -176,7 +174,7 @@ export abstract class AppView<T> {
}
private _destroyRecurse() {
if (this.destroyed) {
if (this.cdMode === ChangeDetectorStatus.Destroyed) {
return;
}
var children = this.contentChildren;
@ -189,7 +187,7 @@ export abstract class AppView<T> {
}
this.destroyLocal();
this.destroyed = true;
this.cdMode = ChangeDetectorStatus.Destroyed;
}
destroyLocal() {
@ -254,17 +252,16 @@ export abstract class AppView<T> {
detectChanges(throwOnChange: boolean): void {
var s = _scope_check(this.clazz);
if (this.cdMode === ChangeDetectionStrategy.Checked ||
this.cdState === ChangeDetectorState.Errored)
if (this.cdMode === ChangeDetectorStatus.Checked ||
this.cdMode === ChangeDetectorStatus.Errored)
return;
if (this.destroyed) {
if (this.cdMode === ChangeDetectorStatus.Destroyed) {
this.throwDestroyedError('detectChanges');
}
this.detectChangesInternal(throwOnChange);
if (this.cdMode === ChangeDetectionStrategy.CheckOnce)
this.cdMode = ChangeDetectionStrategy.Checked;
if (this.cdMode === ChangeDetectorStatus.CheckOnce) this.cdMode = ChangeDetectorStatus.Checked;
this.cdState = ChangeDetectorState.CheckedBefore;
this.numberOfChecks++;
wtfLeave(s);
}
@ -279,7 +276,7 @@ export abstract class AppView<T> {
detectContentChildrenChanges(throwOnChange: boolean) {
for (var i = 0; i < this.contentChildren.length; ++i) {
var child = this.contentChildren[i];
if (child.cdMode === ChangeDetectionStrategy.Detached) continue;
if (child.cdMode === ChangeDetectorStatus.Detached) continue;
child.detectChanges(throwOnChange);
}
}
@ -287,7 +284,7 @@ export abstract class AppView<T> {
detectViewChildrenChanges(throwOnChange: boolean) {
for (var i = 0; i < this.viewChildren.length; ++i) {
var child = this.viewChildren[i];
if (child.cdMode === ChangeDetectionStrategy.Detached) continue;
if (child.cdMode === ChangeDetectorStatus.Detached) continue;
child.detectChanges(throwOnChange);
}
}
@ -304,13 +301,13 @@ export abstract class AppView<T> {
this.viewContainerElement = null;
}
markAsCheckOnce(): void { this.cdMode = ChangeDetectionStrategy.CheckOnce; }
markAsCheckOnce(): void { this.cdMode = ChangeDetectorStatus.CheckOnce; }
markPathToRootAsCheckOnce(): void {
let c: AppView<any> = this;
while (isPresent(c) && c.cdMode !== ChangeDetectionStrategy.Detached) {
if (c.cdMode === ChangeDetectionStrategy.Checked) {
c.cdMode = ChangeDetectionStrategy.CheckOnce;
while (isPresent(c) && c.cdMode !== ChangeDetectorStatus.Detached) {
if (c.cdMode === ChangeDetectorStatus.Checked) {
c.cdMode = ChangeDetectorStatus.CheckOnce;
}
let parentEl =
c.type === ViewType.COMPONENT ? c.declarationAppElement : c.viewContainerElement;
@ -328,7 +325,7 @@ export class DebugAppView<T> extends AppView<T> {
constructor(
clazz: any, componentType: RenderComponentType, type: ViewType, viewUtils: ViewUtils,
parentInjector: Injector, declarationAppElement: AppElement, cdMode: ChangeDetectionStrategy,
parentInjector: Injector, declarationAppElement: AppElement, cdMode: ChangeDetectorStatus,
public staticNodeDebugInfos: StaticNodeDebugInfo[]) {
super(clazz, componentType, type, viewUtils, parentInjector, declarationAppElement, cdMode);
}
@ -393,7 +390,7 @@ export class DebugAppView<T> extends AppView<T> {
private _rethrowWithContext(e: any, stack: any) {
if (!(e instanceof ViewWrappedException)) {
if (!(e instanceof ExpressionChangedAfterItHasBeenCheckedException)) {
this.cdState = ChangeDetectorState.Errored;
this.cdMode = ChangeDetectorStatus.Errored;
}
if (isPresent(this._currentDebugContext)) {
throw new ViewWrappedException(e, stack, this._currentDebugContext);

View File

@ -7,7 +7,7 @@
*/
import {ChangeDetectorRef} from '../change_detection/change_detector_ref';
import {ChangeDetectionStrategy} from '../change_detection/constants';
import {ChangeDetectionStrategy, ChangeDetectorStatus} from '../change_detection/constants';
import {unimplemented} from '../facade/exceptions';
import {AppView} from './view';
@ -89,7 +89,7 @@ export abstract class EmbeddedViewRef<C> extends ViewRef {
export class ViewRef_<C> implements EmbeddedViewRef<C>, ChangeDetectorRef {
/** @internal */
_originalMode: ChangeDetectionStrategy;
_originalMode: ChangeDetectorStatus;
constructor(private _view: AppView<C>) {
this._view = _view;
@ -105,7 +105,7 @@ export class ViewRef_<C> implements EmbeddedViewRef<C>, ChangeDetectorRef {
get destroyed(): boolean { return this._view.destroyed; }
markForCheck(): void { this._view.markPathToRootAsCheckOnce(); }
detach(): void { this._view.cdMode = ChangeDetectionStrategy.Detached; }
detach(): void { this._view.cdMode = ChangeDetectorStatus.Detached; }
detectChanges(): void { this._view.detectChanges(false); }
checkNoChanges(): void { this._view.detectChanges(true); }
reattach(): void {