feat(core): split ChangeDetectorStrategy into ChangeDetectionStrategy and ChangeDetectorStatus
This commit is contained in:
@ -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.
|
||||
*/
|
||||
|
@ -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):
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user