refactor(change_detection): made ChangeDetector and ProtoChangeDetector interfaces
List of changes: - Makes ChangeDetector and ProtoChangeDetector interfaces - Assigns a unique id to every detector
This commit is contained in:
@ -2,19 +2,17 @@ import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {ChangeDetectorRef} from './change_detector_ref';
|
||||
import {ChangeDetector} from './interfaces';
|
||||
import {Locals} from './parser/locals';
|
||||
import {CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED, ON_PUSH} from './constants';
|
||||
|
||||
export class AbstractChangeDetector extends ChangeDetector {
|
||||
export class AbstractChangeDetector implements ChangeDetector {
|
||||
lightDomChildren: List<any> = [];
|
||||
shadowDomChildren: List<any> = [];
|
||||
parent: ChangeDetector;
|
||||
mode: string = null;
|
||||
ref: ChangeDetectorRef;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.ref = new ChangeDetectorRef(this);
|
||||
}
|
||||
constructor(public id: string) { this.ref = new ChangeDetectorRef(this); }
|
||||
|
||||
addChild(cd: ChangeDetector): void {
|
||||
this.lightDomChildren.push(cd);
|
||||
@ -51,6 +49,11 @@ export class AbstractChangeDetector extends ChangeDetector {
|
||||
}
|
||||
|
||||
detectChangesInRecords(throwOnChange: boolean): void {}
|
||||
|
||||
hydrate(context: any, locals: Locals, directives: any): void {}
|
||||
|
||||
dehydrate(): void {}
|
||||
|
||||
callOnAllChangesDone(): void {}
|
||||
|
||||
_detectChangesInLightDomChildren(throwOnChange: boolean): void {
|
||||
|
@ -38,7 +38,7 @@ export class ChangeDetectorJITGenerator {
|
||||
_fieldNames: List<string>;
|
||||
_pipeNames: List<string>;
|
||||
|
||||
constructor(public typeName: string, public changeDetectionStrategy: string,
|
||||
constructor(public id: string, public changeDetectionStrategy: string,
|
||||
public records: List<ProtoRecord>, public directiveRecords: List<any>) {
|
||||
this._localNames = this._getLocalNames(records);
|
||||
this._changeNames = this._getChangeNames(this._localNames);
|
||||
@ -48,10 +48,7 @@ export class ChangeDetectorJITGenerator {
|
||||
|
||||
_getLocalNames(records: List<ProtoRecord>): List<string> {
|
||||
var index = 0;
|
||||
var names = records.map((r) => {
|
||||
var sanitizedName = r.name.replace(new RegExp("\\W", "g"), '');
|
||||
return `${sanitizedName}${index++}`
|
||||
});
|
||||
var names = records.map((r) => { return _sanitizeName(`${r.name}${index++}`); });
|
||||
return ["context"].concat(names);
|
||||
}
|
||||
|
||||
@ -68,9 +65,10 @@ export class ChangeDetectorJITGenerator {
|
||||
}
|
||||
|
||||
generate(): Function {
|
||||
var typeName = _sanitizeName(`ChangeDetector_${this.id}`);
|
||||
var classDefinition = `
|
||||
var ${this.typeName} = function ${this.typeName}(dispatcher, pipeRegistry, protos, directiveRecords) {
|
||||
${ABSTRACT_CHANGE_DETECTOR}.call(this);
|
||||
var ${typeName} = function ${typeName}(dispatcher, pipeRegistry, protos, directiveRecords) {
|
||||
${ABSTRACT_CHANGE_DETECTOR}.call(this, ${JSON.stringify(this.id)});
|
||||
${DISPATCHER_ACCESSOR} = dispatcher;
|
||||
${PIPE_REGISTRY_ACCESSOR} = pipeRegistry;
|
||||
${PROTOS_ACCESSOR} = protos;
|
||||
@ -80,9 +78,9 @@ export class ChangeDetectorJITGenerator {
|
||||
${this._genFieldDefinitions()}
|
||||
}
|
||||
|
||||
${this.typeName}.prototype = Object.create(${ABSTRACT_CHANGE_DETECTOR}.prototype);
|
||||
${typeName}.prototype = Object.create(${ABSTRACT_CHANGE_DETECTOR}.prototype);
|
||||
|
||||
${this.typeName}.prototype.detectChangesInRecords = function(throwOnChange) {
|
||||
${typeName}.prototype.detectChangesInRecords = function(throwOnChange) {
|
||||
if (!this.hydrated()) {
|
||||
${UTIL}.throwDehydrated();
|
||||
}
|
||||
@ -99,11 +97,11 @@ export class ChangeDetectorJITGenerator {
|
||||
${ALREADY_CHECKED_ACCESSOR} = true;
|
||||
}
|
||||
|
||||
${this.typeName}.prototype.callOnAllChangesDone = function() {
|
||||
${typeName}.prototype.callOnAllChangesDone = function() {
|
||||
${this._genCallOnAllChangesDoneBody()}
|
||||
}
|
||||
|
||||
${this.typeName}.prototype.hydrate = function(context, locals, directives) {
|
||||
${typeName}.prototype.hydrate = function(context, locals, directives) {
|
||||
${MODE_ACCESSOR} = "${ChangeDetectionUtil.changeDetectionMode(this.changeDetectionStrategy)}";
|
||||
${CONTEXT_ACCESSOR} = context;
|
||||
${LOCALS_ACCESSOR} = locals;
|
||||
@ -112,21 +110,20 @@ export class ChangeDetectorJITGenerator {
|
||||
${ALREADY_CHECKED_ACCESSOR} = false;
|
||||
}
|
||||
|
||||
${this.typeName}.prototype.dehydrate = function() {
|
||||
${typeName}.prototype.dehydrate = function() {
|
||||
${this._genPipeOnDestroy()}
|
||||
${this._genFieldDefinitions()}
|
||||
${LOCALS_ACCESSOR} = null;
|
||||
}
|
||||
|
||||
${this.typeName}.prototype.hydrated = function() {
|
||||
${typeName}.prototype.hydrated = function() {
|
||||
return ${CONTEXT_ACCESSOR} !== null;
|
||||
}
|
||||
|
||||
return function(dispatcher, pipeRegistry) {
|
||||
return new ${this.typeName}(dispatcher, pipeRegistry, protos, directiveRecords);
|
||||
return new ${typeName}(dispatcher, pipeRegistry, protos, directiveRecords);
|
||||
}
|
||||
`;
|
||||
|
||||
return new Function('AbstractChangeDetector', 'ChangeDetectionUtil', 'protos',
|
||||
'directiveRecords', classDefinition)(
|
||||
AbstractChangeDetector, ChangeDetectionUtil, this.records, this.directiveRecords);
|
||||
@ -444,3 +441,7 @@ export class ChangeDetectorJITGenerator {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
function _sanitizeName(s: string): string {
|
||||
return s.replace(new RegExp("\\W", "g"), '');
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
|
||||
directives: any = null;
|
||||
alreadyChecked: boolean = false;
|
||||
|
||||
constructor(private changeControlStrategy: string, private dispatcher: any,
|
||||
constructor(id: string, private changeControlStrategy: string, private dispatcher: any,
|
||||
private pipeRegistry: PipeRegistry, private protos: List<ProtoRecord>,
|
||||
private directiveRecords: List<any>) {
|
||||
super();
|
||||
super(id);
|
||||
this.values = ListWrapper.createFixedSize(protos.length + 1);
|
||||
this.pipes = ListWrapper.createFixedSize(protos.length + 1);
|
||||
this.prevContexts = ListWrapper.createFixedSize(protos.length + 1);
|
||||
|
@ -3,10 +3,6 @@ import {Locals} from './parser/locals';
|
||||
import {BindingRecord} from './binding_record';
|
||||
import {DirectiveRecord} from './directive_record';
|
||||
|
||||
export class ProtoChangeDetector {
|
||||
instantiate(dispatcher: any): ChangeDetector { return null; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface used by Angular to control the change detection strategy for an application.
|
||||
*
|
||||
@ -39,27 +35,30 @@ export class ChangeDetection {
|
||||
}
|
||||
}
|
||||
|
||||
export class ChangeDispatcher {
|
||||
notifyOnBinding(bindingRecord: BindingRecord, value: any) {}
|
||||
export interface ChangeDispatcher {
|
||||
notifyOnBinding(bindingRecord: BindingRecord, value: any): void;
|
||||
notifyOnAllChangesDone(): void;
|
||||
}
|
||||
|
||||
export class ChangeDetector {
|
||||
export interface ChangeDetector {
|
||||
parent: ChangeDetector;
|
||||
mode: string;
|
||||
|
||||
addChild(cd: ChangeDetector): void {}
|
||||
addShadowDomChild(cd: ChangeDetector): void {}
|
||||
removeChild(cd: ChangeDetector): void {}
|
||||
removeShadowDomChild(cd: ChangeDetector): void {}
|
||||
remove(): void {}
|
||||
hydrate(context: any, locals: Locals, directives: any): void {}
|
||||
dehydrate(): void {}
|
||||
markPathToRootAsCheckOnce(): void {}
|
||||
addChild(cd: ChangeDetector): void;
|
||||
addShadowDomChild(cd: ChangeDetector): void;
|
||||
removeChild(cd: ChangeDetector): void;
|
||||
removeShadowDomChild(cd: ChangeDetector): void;
|
||||
remove(): void;
|
||||
hydrate(context: any, locals: Locals, directives: any): void;
|
||||
dehydrate(): void;
|
||||
markPathToRootAsCheckOnce(): void;
|
||||
|
||||
detectChanges(): void {}
|
||||
checkNoChanges(): void {}
|
||||
detectChanges(): void;
|
||||
checkNoChanges(): void;
|
||||
}
|
||||
|
||||
export interface ProtoChangeDetector { instantiate(dispatcher: any): ChangeDetector; }
|
||||
|
||||
export class ChangeDetectorDefinition {
|
||||
constructor(public id: string, public strategy: string, public variableNames: List<string>,
|
||||
public bindingRecords: List<BindingRecord>,
|
||||
|
@ -6,12 +6,10 @@ import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
|
||||
import {coalesce} from './coalesce';
|
||||
import {ProtoRecordBuilder} from './proto_change_detector';
|
||||
|
||||
var _jitProtoChangeDetectorClassCounter: number = 0;
|
||||
export class JitProtoChangeDetector extends ProtoChangeDetector {
|
||||
export class JitProtoChangeDetector implements ProtoChangeDetector {
|
||||
_factory: Function;
|
||||
|
||||
constructor(private _pipeRegistry, private definition: ChangeDetectorDefinition) {
|
||||
super();
|
||||
this._factory = this._createFactory(definition);
|
||||
}
|
||||
|
||||
@ -25,10 +23,8 @@ export class JitProtoChangeDetector extends ProtoChangeDetector {
|
||||
var recordBuilder = new ProtoRecordBuilder();
|
||||
ListWrapper.forEach(definition.bindingRecords,
|
||||
(b) => { recordBuilder.add(b, definition.variableNames); });
|
||||
var c = _jitProtoChangeDetectorClassCounter++;
|
||||
var records = coalesce(recordBuilder.records);
|
||||
var typeName = `ChangeDetector${c}`;
|
||||
return new ChangeDetectorJITGenerator(typeName, definition.strategy, records,
|
||||
return new ChangeDetectorJITGenerator(definition.id, definition.strategy, records,
|
||||
this.definition.directiveRecords)
|
||||
.generate();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import {coalesce} from './coalesce';
|
||||
|
||||
export {Function as PregenProtoChangeDetectorFactory};
|
||||
|
||||
export class PregenProtoChangeDetector extends ProtoChangeDetector {
|
||||
export class PregenProtoChangeDetector implements ProtoChangeDetector {
|
||||
static isSupported(): boolean { return false; }
|
||||
|
||||
instantiate(dispatcher: any): ChangeDetector {
|
||||
|
@ -25,12 +25,7 @@ import {
|
||||
SafeMethodCall
|
||||
} from './parser/ast';
|
||||
|
||||
import {
|
||||
ChangeDispatcher,
|
||||
ChangeDetector,
|
||||
ProtoChangeDetector,
|
||||
ChangeDetectorDefinition
|
||||
} from './interfaces';
|
||||
import {ChangeDetector, ProtoChangeDetector, ChangeDetectorDefinition} from './interfaces';
|
||||
import {ChangeDetectionUtil} from './change_detection_util';
|
||||
import {DynamicChangeDetector} from './dynamic_change_detector';
|
||||
import {PipeRegistry} from './pipes/pipe_registry';
|
||||
@ -41,17 +36,17 @@ import {coalesce} from './coalesce';
|
||||
|
||||
import {ProtoRecord, RecordType} from './proto_record';
|
||||
|
||||
export class DynamicProtoChangeDetector extends ProtoChangeDetector {
|
||||
export class DynamicProtoChangeDetector implements ProtoChangeDetector {
|
||||
_records: List<ProtoRecord>;
|
||||
|
||||
constructor(private _pipeRegistry: PipeRegistry, private definition: ChangeDetectorDefinition) {
|
||||
super();
|
||||
this._records = this._createRecords(definition);
|
||||
}
|
||||
|
||||
instantiate(dispatcher: any) {
|
||||
return new DynamicChangeDetector(this.definition.strategy, dispatcher, this._pipeRegistry,
|
||||
this._records, this.definition.directiveRecords);
|
||||
return new DynamicChangeDetector(this.definition.id, this.definition.strategy, dispatcher,
|
||||
this._pipeRegistry, this._records,
|
||||
this.definition.directiveRecords);
|
||||
}
|
||||
|
||||
_createRecords(definition: ChangeDetectorDefinition) {
|
||||
|
Reference in New Issue
Block a user