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:
parent
e41d7451bf
commit
69926dd002
|
@ -5,12 +5,7 @@
|
|||
*/
|
||||
|
||||
export {
|
||||
CHECK_ONCE,
|
||||
CHECK_ALWAYS,
|
||||
DETACHED,
|
||||
CHECKED,
|
||||
ON_PUSH,
|
||||
DEFAULT,
|
||||
ChangeDetectionStrategy,
|
||||
|
||||
ExpressionChangedAfterItHasBeenCheckedException,
|
||||
ChangeDetectionError,
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
BindingRecord,
|
||||
DirectiveRecord,
|
||||
ProtoChangeDetector,
|
||||
DEFAULT,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorDefinition,
|
||||
ChangeDetectorGenConfig,
|
||||
ASTWithSource
|
||||
|
@ -305,7 +305,7 @@ function _getChangeDetectorDefinitions(
|
|||
bindingRecordsCreator.getEventBindingRecords(elementBinders, allRenderDirectiveMetadata);
|
||||
var directiveRecords =
|
||||
bindingRecordsCreator.getDirectiveRecords(elementBinders, allRenderDirectiveMetadata);
|
||||
var strategyName = DEFAULT;
|
||||
var strategyName = ChangeDetectionStrategy.Default;
|
||||
if (pvWithIndex.renderProtoView.type === ViewType.COMPONENT) {
|
||||
strategyName = hostComponentMetadata.changeDetection;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
library angular2.src.core.metadata;
|
||||
|
||||
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/directives.dart";
|
||||
import "./metadata/view.dart";
|
||||
|
@ -35,7 +36,7 @@ class Component extends ComponentMetadata {
|
|||
const Component({String selector, List<String> properties,
|
||||
List<String> events, Map<String, String> host,
|
||||
List<LifecycleEvent> lifecycle, List bindings, String exportAs,
|
||||
bool compileChildren, List viewBindings, String changeDetection})
|
||||
bool compileChildren, List viewBindings, ChangeDetectionStrategy changeDetection})
|
||||
: super(
|
||||
selector: selector,
|
||||
properties: properties,
|
||||
|
|
|
@ -33,6 +33,7 @@ import {
|
|||
} from './metadata/directives';
|
||||
|
||||
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 {Type} from 'angular2/src/core/facade/lang';
|
||||
|
@ -191,7 +192,7 @@ export interface ComponentFactory {
|
|||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: List<any>,
|
||||
changeDetection?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
}): ComponentDecorator;
|
||||
new (obj: {
|
||||
selector?: string,
|
||||
|
@ -203,7 +204,7 @@ export interface ComponentFactory {
|
|||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: List<any>,
|
||||
changeDetection?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
}): ComponentMetadata;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {CONST, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
import {List} from 'angular2/src/core/facade/collection';
|
||||
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.
|
||||
|
@ -795,14 +795,12 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||
* Defines the used change detection strategy.
|
||||
*
|
||||
* When a component is instantiated, Angular creates a change detector, which is responsible for
|
||||
* propagating
|
||||
* the component's bindings.
|
||||
* propagating the component's bindings.
|
||||
*
|
||||
* The `changeDetection` property defines, whether the change detection will be checked every time
|
||||
* or only when the component
|
||||
* tells it to do so.
|
||||
* or only when the component tells it to do so.
|
||||
*/
|
||||
changeDetection: string;
|
||||
changeDetection: ChangeDetectionStrategy;
|
||||
|
||||
/**
|
||||
* 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>;
|
||||
|
||||
constructor({selector, properties, events, host, exportAs, lifecycle, bindings, viewBindings,
|
||||
changeDetection = DEFAULT, compileChildren = true}: {
|
||||
changeDetection = ChangeDetectionStrategy.Default, compileChildren = true}: {
|
||||
selector?: string,
|
||||
properties?: List<string>,
|
||||
events?: List<string>,
|
||||
|
@ -857,7 +855,7 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: List<any>,
|
||||
changeDetection?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
} = {}) {
|
||||
super({
|
||||
selector: selector,
|
||||
|
|
|
@ -46,7 +46,7 @@ var _observableStrategy = new ObservableStrategy();
|
|||
* ```
|
||||
* @Component({
|
||||
* selector: "task-cmp",
|
||||
* changeDetection: ON_PUSH
|
||||
* changeDetection: ChangeDetectionStrategy.OnPush
|
||||
* })
|
||||
* @View({
|
||||
* template: "Task Description {{ description | async }}"
|
||||
|
|
|
@ -7,7 +7,10 @@ import {
|
|||
StringMap,
|
||||
StringMapWrapper
|
||||
} 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:
|
||||
|
@ -155,7 +158,7 @@ export class RenderDirectiveMetadata {
|
|||
callOnCheck: boolean;
|
||||
callOnInit: boolean;
|
||||
callOnAllChangesDone: boolean;
|
||||
changeDetection: string;
|
||||
changeDetection: ChangeDetectionStrategy;
|
||||
exportAs: string;
|
||||
hostListeners: Map<string, string>;
|
||||
hostProperties: Map<string, string>;
|
||||
|
@ -185,7 +188,7 @@ export class RenderDirectiveMetadata {
|
|||
callOnCheck?: boolean,
|
||||
callOnInit?: boolean,
|
||||
callOnAllChangesDone?: boolean,
|
||||
changeDetection?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
exportAs?: string
|
||||
}) {
|
||||
this.id = id;
|
||||
|
@ -224,7 +227,7 @@ export class RenderDirectiveMetadata {
|
|||
callOnCheck?: boolean,
|
||||
callOnInit?: boolean,
|
||||
callOnAllChangesDone?: boolean,
|
||||
changeDetection?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
exportAs?: string
|
||||
}): RenderDirectiveMetadata {
|
||||
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 {isBlank, isPresent} from 'angular2/src/core/facade/lang';
|
||||
import {
|
||||
DEFAULT,
|
||||
ON_PUSH,
|
||||
ChangeDetectionStrategy,
|
||||
BindingRecord,
|
||||
ChangeDetectorDefinition,
|
||||
DirectiveIndex,
|
||||
|
@ -12,7 +11,6 @@ import {
|
|||
Parser,
|
||||
ChangeDetectorGenConfig
|
||||
} 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 {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
|
||||
|
||||
|
@ -109,15 +107,17 @@ export function getDefinition(id: string): TestDefinition {
|
|||
|
||||
} else if (id == "onPushObserveBinding") {
|
||||
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);
|
||||
|
||||
} 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);
|
||||
|
||||
} else if (id == "onPushObserveDirective") {
|
||||
let cdDef = new ChangeDetectorDefinition(id, ON_PUSH_OBSERVE, [], [], [],
|
||||
let cdDef = new ChangeDetectorDefinition(id, ChangeDetectionStrategy.OnPushObserve, [], [], [],
|
||||
[_DirectiveUpdating.recordNoCallbacks], genConfig);
|
||||
testDef = new TestDefinition(id, cdDef, null);
|
||||
} else if (id == "updateElementProduction") {
|
||||
|
@ -196,7 +196,7 @@ class _ExpressionWithLocals {
|
|||
}
|
||||
|
||||
class _ExpressionWithMode {
|
||||
constructor(private _strategy: string, private _withRecords: boolean,
|
||||
constructor(private _strategy: ChangeDetectionStrategy, private _withRecords: boolean,
|
||||
private _withEvents: boolean) {}
|
||||
|
||||
createChangeDetectorDefinition(): ChangeDetectorDefinition {
|
||||
|
@ -205,10 +205,14 @@ class _ExpressionWithMode {
|
|||
var directiveRecords = [];
|
||||
var eventRecords = [];
|
||||
|
||||
var dirRecordWithDefault =
|
||||
new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 0), changeDetection: DEFAULT});
|
||||
var dirRecordWithOnPush =
|
||||
new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 1), changeDetection: ON_PUSH});
|
||||
var dirRecordWithDefault = new DirectiveRecord({
|
||||
directiveIndex: new DirectiveIndex(0, 0),
|
||||
changeDetection: ChangeDetectionStrategy.Default
|
||||
});
|
||||
var dirRecordWithOnPush = new DirectiveRecord({
|
||||
directiveIndex: new DirectiveIndex(0, 1),
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
});
|
||||
|
||||
if (this._withRecords) {
|
||||
var updateDirWithOnDefaultRecord =
|
||||
|
@ -240,11 +244,14 @@ class _ExpressionWithMode {
|
|||
* Definitions in this map define conditions which allow testing various change detector modes.
|
||||
*/
|
||||
static availableDefinitions: StringMap<string, _ExpressionWithMode> = {
|
||||
'emptyUsingDefaultStrategy': new _ExpressionWithMode(DEFAULT, false, false),
|
||||
'emptyUsingOnPushStrategy': new _ExpressionWithMode(ON_PUSH, false, false),
|
||||
'onPushRecordsUsingDefaultStrategy': new _ExpressionWithMode(DEFAULT, true, false),
|
||||
'onPushWithEvent': new _ExpressionWithMode(ON_PUSH, false, true),
|
||||
'onPushWithHostEvent': new _ExpressionWithMode(ON_PUSH, false, true)
|
||||
'emptyUsingDefaultStrategy':
|
||||
new _ExpressionWithMode(ChangeDetectionStrategy.Default, false, false),
|
||||
'emptyUsingOnPushStrategy':
|
||||
new _ExpressionWithMode(ChangeDetectionStrategy.OnPush, false, false),
|
||||
'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"'
|
||||
];
|
||||
|
||||
var _availableHostEventDefinitions = ['(host-event)="onEvent(\$event)"'];
|
||||
var _availableHostEventDefinitions = ['(host-event)="onEvent(\$event)"'];
|
||||
|
|
|
@ -32,12 +32,7 @@ import {
|
|||
DirectiveIndex,
|
||||
PipeTransform,
|
||||
PipeOnDestroy,
|
||||
CHECK_ALWAYS,
|
||||
CHECK_ONCE,
|
||||
CHECKED,
|
||||
DETACHED,
|
||||
ON_PUSH,
|
||||
DEFAULT,
|
||||
ChangeDetectionStrategy,
|
||||
WrappedValue,
|
||||
DynamicProtoChangeDetector,
|
||||
ChangeDetectorDefinition,
|
||||
|
@ -673,26 +668,26 @@ export function main() {
|
|||
});
|
||||
|
||||
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;
|
||||
expect(cd.mode).toEqual(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;
|
||||
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', () => {
|
||||
var val = _createChangeDetector('a', new TestData('value'));
|
||||
|
||||
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||
val.changeDetector.mode = DETACHED;
|
||||
val.changeDetector.mode = ChangeDetectionStrategy.Detached;
|
||||
val.changeDetector.detectChanges();
|
||||
|
||||
expect(val.dispatcher.log).toEqual([]);
|
||||
|
@ -702,33 +697,33 @@ export function main() {
|
|||
var val = _createChangeDetector('a', new TestData('value'));
|
||||
|
||||
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||
val.changeDetector.mode = CHECKED;
|
||||
val.changeDetector.mode = ChangeDetectionStrategy.Checked;
|
||||
val.changeDetector.detectChanges();
|
||||
|
||||
expect(val.dispatcher.log).toEqual([]);
|
||||
});
|
||||
|
||||
it('should change CHECK_ONCE to CHECKED', () => {
|
||||
it('should change CheckOnce to Checked', () => {
|
||||
var cd = _createChangeDetector('10').changeDetector;
|
||||
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||
cd.mode = CHECK_ONCE;
|
||||
cd.mode = ChangeDetectionStrategy.CheckOnce;
|
||||
|
||||
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;
|
||||
cd.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||
cd.mode = CHECK_ALWAYS;
|
||||
cd.mode = ChangeDetectionStrategy.CheckAlways;
|
||||
|
||||
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 childDirectiveDetectorOnPush;
|
||||
var directives;
|
||||
|
@ -736,53 +731,53 @@ export function main() {
|
|||
beforeEach(() => {
|
||||
childDirectiveDetectorRegular = _createWithoutHydrate('10').changeDetector;
|
||||
childDirectiveDetectorRegular.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||
childDirectiveDetectorRegular.mode = CHECK_ALWAYS;
|
||||
childDirectiveDetectorRegular.mode = ChangeDetectionStrategy.CheckAlways;
|
||||
|
||||
childDirectiveDetectorOnPush =
|
||||
_createWithoutHydrate('emptyUsingOnPushStrategy').changeDetector;
|
||||
childDirectiveDetectorOnPush.hydrate(_DEFAULT_CONTEXT, null, null, null);
|
||||
childDirectiveDetectorOnPush.mode = CHECKED;
|
||||
childDirectiveDetectorOnPush.mode = ChangeDetectionStrategy.Checked;
|
||||
|
||||
directives =
|
||||
new FakeDirectives([new TestData(null), new TestData(null)],
|
||||
[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 =
|
||||
_createWithoutHydrate('onPushRecordsUsingDefaultStrategy').changeDetector;
|
||||
parentDetector.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||
|
||||
parentDetector.detectChanges();
|
||||
|
||||
// making sure that we only change the status of ON_PUSH components
|
||||
expect(childDirectiveDetectorRegular.mode).toEqual(CHECK_ALWAYS);
|
||||
// making sure that we only change the status of OnPush components
|
||||
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;
|
||||
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||
cd.mode = CHECKED;
|
||||
cd.mode = ChangeDetectionStrategy.Checked;
|
||||
|
||||
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;
|
||||
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||
|
||||
cd.handleEvent("host-event", 0, null);
|
||||
|
||||
expect(childDirectiveDetectorOnPush.mode).toEqual(CHECK_ONCE);
|
||||
expect(childDirectiveDetectorOnPush.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||
});
|
||||
|
||||
if (IS_DART) {
|
||||
describe('ON_PUSH_OBSERVE', () => {
|
||||
it('should mark ON_PUSH_OBSERVE detectors as CHECK_ONCE when an observable fires an event',
|
||||
describe('OnPushObserve', () => {
|
||||
it('should mark OnPushObserve detectors as CheckOnce when an observable fires an event',
|
||||
fakeAsync(() => {
|
||||
var context = new TestDirective();
|
||||
context.a = createObservableModel();
|
||||
|
@ -791,15 +786,15 @@ export function main() {
|
|||
cd.hydrate(context, null, directives, null);
|
||||
cd.detectChanges();
|
||||
|
||||
expect(cd.mode).toEqual(CHECKED);
|
||||
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||
|
||||
context.a.pushUpdate();
|
||||
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(() => {
|
||||
var context = createObservableModel();
|
||||
|
||||
|
@ -807,15 +802,15 @@ export function main() {
|
|||
cd.hydrate(context, null, directives, null);
|
||||
cd.detectChanges();
|
||||
|
||||
expect(cd.mode).toEqual(CHECKED);
|
||||
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||
|
||||
context.pushUpdate();
|
||||
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(() => {
|
||||
var dir = createObservableModel();
|
||||
var directives = new FakeDirectives([dir], []);
|
||||
|
@ -824,12 +819,12 @@ export function main() {
|
|||
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
|
||||
cd.detectChanges();
|
||||
|
||||
expect(cd.mode).toEqual(CHECKED);
|
||||
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||
|
||||
dir.pushUpdate();
|
||||
tick();
|
||||
|
||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
||||
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||
}));
|
||||
|
||||
it('should unsubscribe from an old observable when an object changes',
|
||||
|
@ -843,14 +838,14 @@ export function main() {
|
|||
cd.detectChanges();
|
||||
|
||||
context.a = createObservableModel();
|
||||
cd.mode = CHECK_ONCE;
|
||||
cd.mode = ChangeDetectionStrategy.CheckOnce;
|
||||
cd.detectChanges();
|
||||
|
||||
// Updating this model will not reenable the detector. This model is not longer
|
||||
// used.
|
||||
originalModel.pushUpdate();
|
||||
tick();
|
||||
expect(cd.mode).toEqual(CHECKED);
|
||||
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||
}));
|
||||
|
||||
it('should unsubscribe from observables when dehydrating', fakeAsync(() => {
|
||||
|
@ -872,7 +867,7 @@ export function main() {
|
|||
// used.
|
||||
originalModel.pushUpdate();
|
||||
tick();
|
||||
expect(cd.mode).toEqual(CHECKED);
|
||||
expect(cd.mode).toEqual(ChangeDetectionStrategy.Checked);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
@ -887,22 +882,22 @@ export function main() {
|
|||
return val.changeDetector;
|
||||
}
|
||||
|
||||
it('should mark all checked detectors as CHECK_ONCE until reaching a detached one', () => {
|
||||
var root = changeDetector(CHECK_ALWAYS, null);
|
||||
var disabled = changeDetector(DETACHED, root);
|
||||
var parent = changeDetector(CHECKED, disabled);
|
||||
var checkAlwaysChild = changeDetector(CHECK_ALWAYS, parent);
|
||||
var checkOnceChild = changeDetector(CHECK_ONCE, checkAlwaysChild);
|
||||
var checkedChild = changeDetector(CHECKED, checkOnceChild);
|
||||
it('should mark all checked detectors as CheckOnce until reaching a detached one', () => {
|
||||
var root = changeDetector(ChangeDetectionStrategy.CheckAlways, null);
|
||||
var disabled = changeDetector(ChangeDetectionStrategy.Detached, root);
|
||||
var parent = changeDetector(ChangeDetectionStrategy.Checked, disabled);
|
||||
var checkAlwaysChild = changeDetector(ChangeDetectionStrategy.CheckAlways, parent);
|
||||
var checkOnceChild = changeDetector(ChangeDetectionStrategy.CheckOnce, checkAlwaysChild);
|
||||
var checkedChild = changeDetector(ChangeDetectionStrategy.Checked, checkOnceChild);
|
||||
|
||||
checkedChild.markPathToRootAsCheckOnce();
|
||||
|
||||
expect(root.mode).toEqual(CHECK_ALWAYS);
|
||||
expect(disabled.mode).toEqual(DETACHED);
|
||||
expect(parent.mode).toEqual(CHECK_ONCE);
|
||||
expect(checkAlwaysChild.mode).toEqual(CHECK_ALWAYS);
|
||||
expect(checkOnceChild.mode).toEqual(CHECK_ONCE);
|
||||
expect(checkedChild.mode).toEqual(CHECK_ONCE);
|
||||
expect(root.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||
expect(disabled.mode).toEqual(ChangeDetectionStrategy.Detached);
|
||||
expect(parent.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||
expect(checkAlwaysChild.mode).toEqual(ChangeDetectionStrategy.CheckAlways);
|
||||
expect(checkOnceChild.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||
expect(checkedChild.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:angular2/test_lib.dart';
|
|||
import 'package:observe/observe.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/change_detection.dart';
|
||||
|
||||
class MockException implements Error {
|
||||
var message;
|
||||
|
@ -281,7 +282,7 @@ class OnChangeComponent implements OnChange {
|
|||
|
||||
@Component(
|
||||
selector: 'component-with-observable-list',
|
||||
changeDetection: ON_PUSH,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
properties: const ['list'],
|
||||
bindings: const [
|
||||
const Binding(IterableDiffers,
|
||||
|
|
|
@ -58,7 +58,7 @@ import {
|
|||
import {
|
||||
PipeTransform,
|
||||
ChangeDetectorRef,
|
||||
ON_PUSH,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetection,
|
||||
DynamicChangeDetection,
|
||||
ChangeDetectorGenConfig
|
||||
|
@ -635,7 +635,7 @@ export function main() {
|
|||
}));
|
||||
});
|
||||
|
||||
describe("ON_PUSH components", () => {
|
||||
describe("OnPush components", () => {
|
||||
it("should use ChangeDetectorRef to manually request a check",
|
||||
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder, async) => {
|
||||
|
@ -1672,7 +1672,8 @@ class DirectiveWithTitleAndHostProperty {
|
|||
title: string;
|
||||
}
|
||||
|
||||
@Component({selector: 'push-cmp', properties: ['prop'], changeDetection: ON_PUSH})
|
||||
@Component(
|
||||
{selector: 'push-cmp', properties: ['prop'], changeDetection: ChangeDetectionStrategy.OnPush})
|
||||
@View({template: '{{field}}'})
|
||||
@Injectable()
|
||||
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}}'})
|
||||
@Injectable()
|
||||
class PushCmpWithRef {
|
||||
|
@ -1708,7 +1713,7 @@ class PushCmpWithRef {
|
|||
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}}'})
|
||||
@Injectable()
|
||||
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,
|
||||
BindingRecord,
|
||||
DirectiveRecord,
|
||||
DirectiveIndex,
|
||||
DEFAULT
|
||||
DirectiveIndex
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import "package:angular2/src/core/facade/collection.dart"
|
|||
import "common.dart"
|
||||
show Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST;
|
||||
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 {
|
||||
int cellWidth;
|
||||
|
@ -17,7 +17,7 @@ class HasStyle {
|
|||
@Component(
|
||||
selector: "company-name",
|
||||
properties: const ["width: cell-width", "company"],
|
||||
changeDetection: "ON_PUSH_OBSERVE"
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
|
@ -29,7 +29,7 @@ class CompanyNameComponent extends HasStyle {
|
|||
@Component(
|
||||
selector: "opportunity-name",
|
||||
properties: const ["width: cell-width", "opportunity"],
|
||||
changeDetection: "ON_PUSH_OBSERVE"
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
|
@ -41,7 +41,7 @@ class OpportunityNameComponent extends HasStyle {
|
|||
@Component(
|
||||
selector: "offering-name",
|
||||
properties: const ["width: cell-width", "offering"],
|
||||
changeDetection: "ON_PUSH_OBSERVE"
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
|
@ -59,7 +59,7 @@ class Stage {
|
|||
@Component(
|
||||
selector: "stage-buttons",
|
||||
properties: const ["width: cell-width", "offering"],
|
||||
changeDetection: "ON_PUSH_OBSERVE"
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(directives: const [NgFor], template: '''
|
||||
<div [style.width.px]="cellWidth">
|
||||
|
@ -103,7 +103,7 @@ class StageButtonsComponent extends HasStyle {
|
|||
@Component(
|
||||
selector: "account-cell",
|
||||
properties: const ["width: cell-width", "account"],
|
||||
changeDetection: "ON_PUSH_OBSERVE"
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(directives: const [], template: '''
|
||||
<div [style.width.px]="cellWidth">
|
||||
|
@ -117,7 +117,7 @@ class AccountCellComponent extends HasStyle {
|
|||
@Component(
|
||||
selector: "formatted-cell",
|
||||
properties: const ["width: cell-width", "value"],
|
||||
changeDetection: "ON_PUSH_OBSERVE"
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
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/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"
|
||||
show
|
||||
Offering,
|
||||
|
@ -16,7 +16,7 @@ import "random_data.dart" show generateOfferings;
|
|||
import "scroll_item.dart" show ScrollItemComponent;
|
||||
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: '''
|
||||
<div>
|
||||
<div id="scrollDiv"
|
||||
|
|
|
@ -8,7 +8,7 @@ import "cells.dart"
|
|||
StageButtonsComponent,
|
||||
AccountCellComponent,
|
||||
FormattedCellComponent;
|
||||
import "package:angular2/angular2.dart" show Component, Directive, View;
|
||||
import "package:angular2/angular2.dart" show Component, Directive, View, ChangeDetectionStrategy;
|
||||
import "common.dart"
|
||||
show
|
||||
Offering,
|
||||
|
@ -25,7 +25,8 @@ import "common.dart"
|
|||
END_DATE_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(
|
||||
directives: const [
|
||||
CompanyNameComponent,
|
||||
|
|
|
@ -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/src/generated/element.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
|
||||
/// instance of [Annotation], [NodeList<Annotation>], ListLiteral, or
|
||||
|
@ -63,7 +64,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||
bool _callOnCheck;
|
||||
bool _callOnInit;
|
||||
bool _callOnAllChangesDone;
|
||||
String _changeDetection;
|
||||
ChangeDetectionStrategy _changeDetection;
|
||||
List<String> _events;
|
||||
|
||||
final ConstantEvaluator _evaluator = new ConstantEvaluator();
|
||||
|
@ -283,6 +284,9 @@ class _DirectiveMetadataVisitor extends Object
|
|||
|
||||
void _populateChangeDetection(Expression value) {
|
||||
_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;
|
||||
|
||||
import 'package:angular2/src/core/render/api.dart';
|
||||
import 'package:angular2/src/core/render/dom/convert.dart';
|
||||
import 'convert.dart';
|
||||
import 'logging.dart';
|
||||
|
||||
/// Metadata about directives and directive aliases.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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/codegen_facade.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
|
||||
/// detail and should not be visible to users.
|
||||
final String _changeDetectorTypeName;
|
||||
final String _changeDetectionStrategy;
|
||||
final ChangeDetectionStrategy _changeDetectionStrategy;
|
||||
final List<DirectiveRecord> _directiveRecords;
|
||||
final List<ProtoRecord> _records;
|
||||
final List<EventBinding> _eventBindings;
|
||||
|
@ -84,6 +85,9 @@ class _CodegenState {
|
|||
final ChangeDetectorGenConfig _genConfig;
|
||||
final List<BindingTarget> _propertyBindingTargets;
|
||||
|
||||
String get _changeDetectionStrategyAsCode =>
|
||||
_changeDetectionStrategy == null ? 'null' : '${_GEN_PREFIX}.${_changeDetectionStrategy}';
|
||||
|
||||
_CodegenState._(
|
||||
this._changeDetectorDefId,
|
||||
this._contextTypeName,
|
||||
|
@ -129,7 +133,7 @@ class _CodegenState {
|
|||
dispatcher, ${_records.length},
|
||||
${_changeDetectorTypeName}.gen_propertyBindingTargets,
|
||||
${_changeDetectorTypeName}.gen_directiveIndices,
|
||||
${codify(_changeDetectionStrategy)}) {
|
||||
${_changeDetectionStrategyAsCode}) {
|
||||
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 '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/logging.dart';
|
||||
import 'package:angular2/src/transform/common/ng_deps.dart';
|
||||
|
@ -122,7 +123,7 @@ void allTests() {
|
|||
it('should parse changeDetection.', () async {
|
||||
var metadata = await readMetadata('directive_metadata_extractor/'
|
||||
'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.',
|
||||
|
|
|
@ -2,7 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
|
|||
|
||||
import 'hello.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show Component, Directive, View, NgElement, LifecycleEvent;
|
||||
show Component, Directive, View, NgElement, LifecycleEvent, ChangeDetectionStrategy;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
|
@ -12,7 +12,7 @@ void initReflector(reflector) {
|
|||
..registerType(
|
||||
HelloCmp,
|
||||
new ReflectionInfo(
|
||||
const [const Component(changeDetection: 'CHECK_ONCE')],
|
||||
const [const Component(changeDetection: ChangeDetectionStrategy.CheckOnce)],
|
||||
const [const []],
|
||||
() => new HelloCmp()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue