refactor(change_detection): removed directive and binding mementos
This commit is contained in:
58
modules/angular2/src/change_detection/binding_record.js
vendored
Normal file
58
modules/angular2/src/change_detection/binding_record.js
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {SetterFn} from 'angular2/src/reflection/types';
|
||||
import {AST} from './parser/ast';
|
||||
import {DirectiveRecord} from './directive_record';
|
||||
|
||||
const DIRECTIVE="directive";
|
||||
const ELEMENT="element";
|
||||
const TEXT_NODE="textNode";
|
||||
|
||||
export class BindingRecord {
|
||||
mode:string;
|
||||
ast:AST;
|
||||
|
||||
elementIndex:number;
|
||||
propertyName:string;
|
||||
setter:SetterFn;
|
||||
|
||||
directiveRecord:DirectiveRecord;
|
||||
|
||||
constructor(mode:string, ast:AST, elementIndex:number, propertyName:string, setter:SetterFn, directiveRecord:DirectiveRecord) {
|
||||
this.mode = mode;
|
||||
this.ast = ast;
|
||||
|
||||
this.elementIndex = elementIndex;
|
||||
this.propertyName = propertyName;
|
||||
this.setter = setter;
|
||||
|
||||
this.directiveRecord = directiveRecord;
|
||||
}
|
||||
|
||||
callOnChange() {
|
||||
return isPresent(this.directiveRecord) && this.directiveRecord.callOnChange;
|
||||
}
|
||||
|
||||
isDirective() {
|
||||
return this.mode === DIRECTIVE;
|
||||
}
|
||||
|
||||
isElement() {
|
||||
return this.mode === ELEMENT;
|
||||
}
|
||||
|
||||
isTextNode() {
|
||||
return this.mode === TEXT_NODE;
|
||||
}
|
||||
|
||||
static createForDirective(ast:AST, propertyName:string, setter:SetterFn, directiveRecord:DirectiveRecord) {
|
||||
return new BindingRecord(DIRECTIVE, ast, 0, propertyName, setter, directiveRecord);
|
||||
}
|
||||
|
||||
static createForElement(ast:AST, elementIndex:number, propertyName:string) {
|
||||
return new BindingRecord(ELEMENT, ast, elementIndex, propertyName, null, null);
|
||||
}
|
||||
|
||||
static createForTextNode(ast:AST, elementIndex:number) {
|
||||
return new BindingRecord(TEXT_NODE, ast, elementIndex, null, null, null);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/faca
|
||||
|
||||
import {AbstractChangeDetector} from './abstract_change_detector';
|
||||
import {ChangeDetectionUtil} from './change_detection_util';
|
||||
import {DirectiveRecord} from './directive_record';
|
||||
|
||||
import {
|
||||
ProtoRecord,
|
||||
@ -33,7 +34,7 @@ var UTIL = "ChangeDetectionUtil";
|
||||
var DISPATCHER_ACCESSOR = "this.dispatcher";
|
||||
var PIPE_REGISTRY_ACCESSOR = "this.pipeRegistry";
|
||||
var PROTOS_ACCESSOR = "this.protos";
|
||||
var MEMENTOS_ACCESSOR = "this.directiveMementos";
|
||||
var DIRECTIVES_ACCESSOR = "this.directiveRecords";
|
||||
var CONTEXT_ACCESSOR = "this.context";
|
||||
var CHANGE_LOCAL = "change";
|
||||
var CHANGES_LOCAL = "changes";
|
||||
@ -51,19 +52,19 @@ ${notifyOnAllChangesDone}
|
||||
${setContext};
|
||||
|
||||
return function(dispatcher, pipeRegistry) {
|
||||
return new ${type}(dispatcher, pipeRegistry, protos, directiveMementos);
|
||||
return new ${type}(dispatcher, pipeRegistry, protos, directiveRecords);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function constructorTemplate(type:string, fieldsDefinitions:string):string {
|
||||
return `
|
||||
var ${type} = function ${type}(dispatcher, pipeRegistry, protos, directiveMementos) {
|
||||
var ${type} = function ${type}(dispatcher, pipeRegistry, protos, directiveRecords) {
|
||||
${ABSTRACT_CHANGE_DETECTOR}.call(this);
|
||||
${DISPATCHER_ACCESSOR} = dispatcher;
|
||||
${PIPE_REGISTRY_ACCESSOR} = pipeRegistry;
|
||||
${PROTOS_ACCESSOR} = protos;
|
||||
${MEMENTOS_ACCESSOR} = directiveMementos;
|
||||
${DIRECTIVES_ACCESSOR} = directiveRecords;
|
||||
${LOCALS_ACCESSOR} = null;
|
||||
${fieldsDefinitions}
|
||||
}
|
||||
@ -80,7 +81,7 @@ function hydrateTemplate(type:string, mode:string, fieldDefinitions:string, pipe
|
||||
directiveFieldNames:List<String>):string {
|
||||
var directiveInit = "";
|
||||
for(var i = 0; i < directiveFieldNames.length; ++i) {
|
||||
directiveInit += `${directiveFieldNames[i]} = this.directiveMementos[${i}].directive(directives);\n`;
|
||||
directiveInit += `${directiveFieldNames[i]} = directives.directive(this.directiveRecords[${i}]);\n`;
|
||||
}
|
||||
|
||||
return `
|
||||
@ -137,7 +138,7 @@ ${records}
|
||||
}
|
||||
|
||||
function pipeCheckTemplate(protoIndex:number, context:string, bindingPropagationConfig:string, pipe:string, pipeType:string,
|
||||
oldValue:string, newValue:string, change:string, invokeMemento:string,
|
||||
oldValue:string, newValue:string, change:string, update:string,
|
||||
addToChanges, lastInDirective:string):string{
|
||||
return `
|
||||
${CURRENT_PROTO} = ${PROTOS_ACCESSOR}[${protoIndex}];
|
||||
@ -151,7 +152,7 @@ if (${pipe} === ${UTIL}.unitialized()) {
|
||||
${newValue} = ${pipe}.transform(${context});
|
||||
if (! ${UTIL}.noChangeMarker(${newValue})) {
|
||||
${change} = true;
|
||||
${invokeMemento}
|
||||
${update}
|
||||
${addToChanges}
|
||||
${oldValue} = ${newValue};
|
||||
}
|
||||
@ -160,13 +161,13 @@ ${lastInDirective}
|
||||
}
|
||||
|
||||
function referenceCheckTemplate(protoIndex:number, assignment:string, oldValue:string, newValue:string, change:string,
|
||||
invokeMemento:string, addToChanges:string, lastInDirective:string):string {
|
||||
update:string, addToChanges:string, lastInDirective:string):string {
|
||||
return `
|
||||
${CURRENT_PROTO} = ${PROTOS_ACCESSOR}[${protoIndex}];
|
||||
${assignment}
|
||||
if (${newValue} !== ${oldValue} || (${newValue} !== ${newValue}) && (${oldValue} !== ${oldValue})) {
|
||||
${change} = true;
|
||||
${invokeMemento}
|
||||
${update}
|
||||
${addToChanges}
|
||||
${oldValue} = ${newValue};
|
||||
}
|
||||
@ -200,7 +201,7 @@ if (${cond}) {
|
||||
}
|
||||
|
||||
function addToChangesTemplate(oldValue:string, newValue:string):string {
|
||||
return `${CHANGES_LOCAL} = ${UTIL}.addChange(${CHANGES_LOCAL}, ${CURRENT_PROTO}.bindingMemento, ${UTIL}.simpleChange(${oldValue}, ${newValue}));`;
|
||||
return `${CHANGES_LOCAL} = ${UTIL}.addChange(${CHANGES_LOCAL}, ${CURRENT_PROTO}.bindingRecord.propertyName, ${UTIL}.simpleChange(${oldValue}, ${newValue}));`;
|
||||
}
|
||||
|
||||
function updateDirectiveTemplate(oldValue:string, newValue:string, directiveProperty:string):string {
|
||||
@ -213,7 +214,7 @@ ${directiveProperty} = ${newValue};
|
||||
function updateElementTemplate(oldValue:string, newValue:string):string {
|
||||
return `
|
||||
if(throwOnChange) ${UTIL}.throwOnChange(${CURRENT_PROTO}, ${UTIL}.simpleChange(${oldValue}, ${newValue}));
|
||||
${DISPATCHER_ACCESSOR}.invokeMementoFor(${CURRENT_PROTO}.bindingMemento, ${newValue});
|
||||
${DISPATCHER_ACCESSOR}.notifyOnBinding(${CURRENT_PROTO}.bindingRecord, ${newValue});
|
||||
`;
|
||||
}
|
||||
|
||||
@ -230,18 +231,18 @@ if(${CHANGES_LOCAL}) {
|
||||
export class ChangeDetectorJITGenerator {
|
||||
typeName:string;
|
||||
records:List<ProtoRecord>;
|
||||
directiveMementos:List;
|
||||
directiveRecords:List;
|
||||
localNames:List<string>;
|
||||
changeNames:List<string>;
|
||||
fieldNames:List<string>;
|
||||
pipeNames:List<string>;
|
||||
changeDetectionStrategy:stirng;
|
||||
|
||||
constructor(typeName:string, changeDetectionStrategy:string, records:List<ProtoRecord>, directiveMementos:List) {
|
||||
constructor(typeName:string, changeDetectionStrategy:string, records:List<ProtoRecord>, directiveRecords:List) {
|
||||
this.typeName = typeName;
|
||||
this.changeDetectionStrategy = changeDetectionStrategy;
|
||||
this.records = records;
|
||||
this.directiveMementos = directiveMementos;
|
||||
this.directiveRecords = directiveRecords;
|
||||
|
||||
this.localNames = this.getLocalNames(records);
|
||||
this.changeNames = this.getChangeNames(this.localNames);
|
||||
@ -273,8 +274,8 @@ export class ChangeDetectorJITGenerator {
|
||||
generate():Function {
|
||||
var text = typeTemplate(this.typeName, this.genConstructor(), this.genDetectChanges(),
|
||||
this.genCallOnAllChangesDone(), this.genHydrate());
|
||||
return new Function('AbstractChangeDetector', 'ChangeDetectionUtil', 'protos', 'directiveMementos', text)
|
||||
(AbstractChangeDetector, ChangeDetectionUtil, this.records, this.directiveMementos);
|
||||
return new Function('AbstractChangeDetector', 'ChangeDetectionUtil', 'protos', 'directiveRecords', text)
|
||||
(AbstractChangeDetector, ChangeDetectionUtil, this.records, this.directiveRecords);
|
||||
}
|
||||
|
||||
genConstructor():string {
|
||||
@ -288,11 +289,11 @@ export class ChangeDetectorJITGenerator {
|
||||
}
|
||||
|
||||
getDirectiveFieldNames():List<string> {
|
||||
return this.directiveMementos.map((d) => this.getDirective(d));
|
||||
return this.directiveRecords.map((d) => this.getDirective(d));
|
||||
}
|
||||
|
||||
getDirective(memento) {
|
||||
return `this.directive_${memento.name}`;
|
||||
getDirective(d:DirectiveRecord) {
|
||||
return `this.directive_${d.name}`;
|
||||
}
|
||||
|
||||
genFieldDefinitions() {
|
||||
@ -320,12 +321,12 @@ export class ChangeDetectorJITGenerator {
|
||||
|
||||
genCallOnAllChangesDone():string {
|
||||
var notifications = [];
|
||||
var mementos = this.directiveMementos;
|
||||
var dirs = this.directiveRecords;
|
||||
|
||||
for (var i = mementos.length - 1; i >= 0; --i) {
|
||||
var memento = mementos[i];
|
||||
if (memento.callOnAllChangesDone) {
|
||||
var directive = `this.directive_${memento.name}`;
|
||||
for (var i = dirs.length - 1; i >= 0; --i) {
|
||||
var dir = dirs[i];
|
||||
if (dir.callOnAllChangesDone) {
|
||||
var directive = `this.directive_${dir.name}`;
|
||||
notifications.push(onAllChangesDoneTemplate(directive));
|
||||
}
|
||||
}
|
||||
@ -363,12 +364,12 @@ export class ChangeDetectorJITGenerator {
|
||||
var pipe = this.pipeNames[r.selfIndex];
|
||||
var bpc = r.mode === RECORD_TYPE_BINDING_PIPE ? "this.bindingPropagationConfig" : "null";
|
||||
|
||||
var invokeMemento = this.genUpdateDirectiveOrElement(r);
|
||||
var update = this.genUpdateDirectiveOrElement(r);
|
||||
var addToChanges = this.genAddToChanges(r);
|
||||
var lastInDirective = this.genNotifyOnChanges(r);
|
||||
|
||||
return pipeCheckTemplate(r.selfIndex - 1, context, bpc, pipe, r.name, oldValue, newValue, change,
|
||||
invokeMemento, addToChanges, lastInDirective);
|
||||
update, addToChanges, lastInDirective);
|
||||
}
|
||||
|
||||
genReferenceCheck(r:ProtoRecord):string {
|
||||
@ -377,12 +378,12 @@ export class ChangeDetectorJITGenerator {
|
||||
var change = this.changeNames[r.selfIndex];
|
||||
var assignment = this.genUpdateCurrentValue(r);
|
||||
|
||||
var invokeMemento = this.genUpdateDirectiveOrElement(r);
|
||||
var update = this.genUpdateDirectiveOrElement(r);
|
||||
var addToChanges = this.genAddToChanges(r);
|
||||
var lastInDirective = this.genNotifyOnChanges(r);
|
||||
|
||||
var check = referenceCheckTemplate(r.selfIndex - 1, assignment, oldValue, newValue, change,
|
||||
invokeMemento, addToChanges, lastInDirective);
|
||||
update, addToChanges, lastInDirective);
|
||||
if (r.isPureFunction()) {
|
||||
return this.ifChangedGuard(r, check);
|
||||
} else {
|
||||
@ -455,8 +456,9 @@ export class ChangeDetectorJITGenerator {
|
||||
var newValue = this.localNames[r.selfIndex];
|
||||
var oldValue = this.fieldNames[r.selfIndex];
|
||||
|
||||
if (isPresent(r.directiveMemento)) {
|
||||
var directiveProperty = `${this.getDirective(r.directiveMemento)}.${r.bindingMemento.propertyName}`;
|
||||
var br = r.bindingRecord;
|
||||
if (br.isDirective()) {
|
||||
var directiveProperty = `${this.getDirective(br.directiveRecord)}.${br.propertyName}`;
|
||||
return updateDirectiveTemplate(oldValue, newValue, directiveProperty);
|
||||
} else {
|
||||
return updateElementTemplate(oldValue, newValue);
|
||||
@ -466,14 +468,13 @@ export class ChangeDetectorJITGenerator {
|
||||
genAddToChanges(r:ProtoRecord):string {
|
||||
var newValue = this.localNames[r.selfIndex];
|
||||
var oldValue = this.fieldNames[r.selfIndex];
|
||||
var callOnChange = r.directiveMemento && r.directiveMemento.callOnChange;
|
||||
return callOnChange ? addToChangesTemplate(oldValue, newValue) : "";
|
||||
return r.bindingRecord.callOnChange() ? addToChangesTemplate(oldValue, newValue) : "";
|
||||
}
|
||||
|
||||
genNotifyOnChanges(r:ProtoRecord):string{
|
||||
var callOnChange = r.directiveMemento && r.directiveMemento.callOnChange;
|
||||
if (r.lastInDirective && callOnChange) {
|
||||
return notifyOnChangesTemplate(this.getDirective(r.directiveMemento));
|
||||
var br = r.bindingRecord;
|
||||
if (r.lastInDirective && br.callOnChange()) {
|
||||
return notifyOnChangesTemplate(this.getDirective(br.directiveRecord));
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ export class ChangeDetectionUtil {
|
||||
return _simpleChange(previousValue, currentValue);
|
||||
}
|
||||
|
||||
static addChange(changes, bindingMemento, change){
|
||||
static addChange(changes, propertyName:string, change){
|
||||
if (isBlank(changes)) {
|
||||
changes = {};
|
||||
}
|
||||
changes[bindingMemento.propertyName] = change;
|
||||
changes[propertyName] = change;
|
||||
return changes;
|
||||
}
|
||||
}
|
@ -46,8 +46,7 @@ function _selfRecord(r:ProtoRecord, contextIndex:number, selfIndex:number):Proto
|
||||
r.fixedArgs,
|
||||
contextIndex,
|
||||
selfIndex,
|
||||
r.bindingMemento,
|
||||
r.directiveMemento,
|
||||
r.bindingRecord,
|
||||
r.expressionAsString,
|
||||
r.lastInBinding,
|
||||
r.lastInDirective
|
||||
@ -74,8 +73,7 @@ function _replaceIndices(r:ProtoRecord, selfIndex:number, indexMap:Map) {
|
||||
r.fixedArgs,
|
||||
contextIndex,
|
||||
selfIndex,
|
||||
r.bindingMemento,
|
||||
r.directiveMemento,
|
||||
r.bindingRecord,
|
||||
r.expressionAsString,
|
||||
r.lastInBinding,
|
||||
r.lastInDirective
|
||||
|
19
modules/angular2/src/change_detection/directive_record.js
vendored
Normal file
19
modules/angular2/src/change_detection/directive_record.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
export class DirectiveRecord {
|
||||
elementIndex:number;
|
||||
directiveIndex:number;
|
||||
callOnAllChangesDone:boolean;
|
||||
callOnChange:boolean;
|
||||
|
||||
constructor(elementIndex:number, directiveIndex:number,
|
||||
callOnAllChangesDone:boolean,
|
||||
callOnChange:boolean) {
|
||||
this.elementIndex = elementIndex;
|
||||
this.directiveIndex = directiveIndex;
|
||||
this.callOnAllChangesDone = callOnAllChangesDone;
|
||||
this.callOnChange = callOnChange;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return `${this.elementIndex}_${this.directiveIndex}`;
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ import {isPresent, isBlank, BaseException, FunctionWrapper} from 'angular2/src/f
|
||||
import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {AbstractChangeDetector} from './abstract_change_detector';
|
||||
import {BindingRecord} from './binding_record';
|
||||
import {DirectiveRecord} from './directive_record';
|
||||
import {PipeRegistry} from './pipes/pipe_registry';
|
||||
import {ChangeDetectionUtil, uninitialized} from './change_detection_util';
|
||||
|
||||
@ -35,11 +37,11 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
|
||||
|
||||
protos:List<ProtoRecord>;
|
||||
directives:any;
|
||||
directiveMementos:List;
|
||||
directiveRecords:List;
|
||||
changeControlStrategy:string;
|
||||
|
||||
constructor(changeControlStrategy:string, dispatcher:any, pipeRegistry:PipeRegistry,
|
||||
protoRecords:List<ProtoRecord>, directiveMementos:List) {
|
||||
protoRecords:List<ProtoRecord>, directiveRecords:List) {
|
||||
super();
|
||||
this.dispatcher = dispatcher;
|
||||
this.pipeRegistry = pipeRegistry;
|
||||
@ -57,7 +59,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
|
||||
this.directives = null;
|
||||
|
||||
this.protos = protoRecords;
|
||||
this.directiveMementos = directiveMementos;
|
||||
this.directiveRecords = directiveRecords;
|
||||
this.changeControlStrategy = changeControlStrategy;
|
||||
}
|
||||
|
||||
@ -99,45 +101,45 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
|
||||
var change = this._check(proto);
|
||||
if (isPresent(change)) {
|
||||
if (throwOnChange) ChangeDetectionUtil.throwOnChange(proto, change);
|
||||
this._updateDirectiveOrElement(change, proto.directiveMemento, proto.bindingMemento);
|
||||
changes = this._addChange(proto.directiveMemento, proto.bindingMemento, change, changes);
|
||||
this._updateDirectiveOrElement(change, proto.bindingRecord);
|
||||
changes = this._addChange(proto.bindingRecord, change, changes);
|
||||
}
|
||||
|
||||
if (proto.lastInDirective && isPresent(changes)) {
|
||||
this._directive(proto.directiveMemento).onChange(changes);
|
||||
this._directive(proto.bindingRecord.directiveRecord).onChange(changes);
|
||||
changes = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callOnAllChangesDone() {
|
||||
var mementos = this.directiveMementos;
|
||||
for (var i = mementos.length - 1; i >= 0; --i) {
|
||||
var memento = mementos[i];
|
||||
if (memento.callOnAllChangesDone) {
|
||||
this._directive(memento).onAllChangesDone();
|
||||
var dirs = this.directiveRecords;
|
||||
for (var i = dirs.length - 1; i >= 0; --i) {
|
||||
var dir = dirs[i];
|
||||
if (dir.callOnAllChangesDone) {
|
||||
this._directive(dir).onAllChangesDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_updateDirectiveOrElement(change, directiveMemento, bindingMemento) {
|
||||
if (isBlank(directiveMemento)) {
|
||||
this.dispatcher.invokeMementoFor(bindingMemento, change.currentValue);
|
||||
_updateDirectiveOrElement(change, bindingRecord) {
|
||||
if (isBlank(bindingRecord.directiveRecord)) {
|
||||
this.dispatcher.notifyOnBinding(bindingRecord, change.currentValue);
|
||||
} else {
|
||||
bindingMemento.setter(this._directive(directiveMemento), change.currentValue);
|
||||
bindingRecord.setter(this._directive(bindingRecord.directiveRecord), change.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
_addChange(directiveMemento, bindingMemento, change, changes) {
|
||||
if (isPresent(directiveMemento) && directiveMemento.callOnChange) {
|
||||
return ChangeDetectionUtil.addChange(changes, bindingMemento, change);
|
||||
_addChange(bindingRecord:BindingRecord, change, changes) {
|
||||
if (bindingRecord.callOnChange()) {
|
||||
return ChangeDetectionUtil.addChange(changes, bindingRecord.propertyName, change);
|
||||
} else {
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
|
||||
_directive(memento) {
|
||||
return memento.directive(this.directives);
|
||||
_directive(directive:DirectiveRecord) {
|
||||
return this.directives.directive(directive);
|
||||
}
|
||||
|
||||
_check(proto:ProtoRecord) {
|
||||
|
@ -1,11 +1,10 @@
|
||||
import {List} from 'angular2/src/facade/collection';
|
||||
import {Locals} from './parser/locals';
|
||||
import {AST} from './parser/ast';
|
||||
import {DEFAULT} from './constants';
|
||||
import {BindingRecord} from './binding_record';
|
||||
|
||||
export class ProtoChangeDetector {
|
||||
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null){}
|
||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveMementos:List):ChangeDetector{
|
||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveRecords:List):ChangeDetector{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -17,7 +16,7 @@ export class ChangeDetection {
|
||||
}
|
||||
|
||||
export class ChangeDispatcher {
|
||||
invokeMementoFor(memento:any, value) {}
|
||||
notifyOnBinding(bindingRecord:BindingRecord, value:any) {}
|
||||
}
|
||||
|
||||
export class ChangeDetector {
|
||||
|
@ -27,6 +27,7 @@ import {ChangeDetectionUtil} from './change_detection_util';
|
||||
import {DynamicChangeDetector} from './dynamic_change_detector';
|
||||
import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
|
||||
import {PipeRegistry} from './pipes/pipe_registry';
|
||||
import {BindingRecord} from './binding_record';
|
||||
|
||||
import {coalesce} from './coalesce';
|
||||
|
||||
@ -45,18 +46,6 @@ import {
|
||||
RECORD_TYPE_INTERPOLATE
|
||||
} from './proto_record';
|
||||
|
||||
export class BindingRecord {
|
||||
ast:AST;
|
||||
bindingMemento:any;
|
||||
directiveMemento:any;
|
||||
|
||||
constructor(ast:AST, bindingMemento:any, directiveMemento:any) {
|
||||
this.ast = ast;
|
||||
this.bindingMemento = bindingMemento;
|
||||
this.directiveMemento = directiveMemento;
|
||||
}
|
||||
}
|
||||
|
||||
export class DynamicProtoChangeDetector extends ProtoChangeDetector {
|
||||
_pipeRegistry:PipeRegistry;
|
||||
_records:List<ProtoRecord>;
|
||||
@ -68,17 +57,17 @@ export class DynamicProtoChangeDetector extends ProtoChangeDetector {
|
||||
this._changeControlStrategy = changeControlStrategy;
|
||||
}
|
||||
|
||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveMementos:List) {
|
||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveRecords:List) {
|
||||
this._createRecordsIfNecessary(bindingRecords, variableBindings);
|
||||
return new DynamicChangeDetector(this._changeControlStrategy, dispatcher,
|
||||
this._pipeRegistry, this._records, directiveMementos);
|
||||
this._pipeRegistry, this._records, directiveRecords);
|
||||
}
|
||||
|
||||
_createRecordsIfNecessary(bindingRecords:List, variableBindings:List) {
|
||||
if (isBlank(this._records)) {
|
||||
var recordBuilder = new ProtoRecordBuilder();
|
||||
ListWrapper.forEach(bindingRecords, (r) => {
|
||||
recordBuilder.addAst(r.ast, r.bindingMemento, r.directiveMemento, variableBindings);
|
||||
ListWrapper.forEach(bindingRecords, (b) => {
|
||||
recordBuilder.addAst(b, variableBindings);
|
||||
});
|
||||
this._records = coalesce(recordBuilder.records);
|
||||
}
|
||||
@ -98,22 +87,22 @@ export class JitProtoChangeDetector extends ProtoChangeDetector {
|
||||
this._changeControlStrategy = changeControlStrategy;
|
||||
}
|
||||
|
||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveMementos:List) {
|
||||
this._createFactoryIfNecessary(bindingRecords, variableBindings, directiveMementos);
|
||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveRecords:List) {
|
||||
this._createFactoryIfNecessary(bindingRecords, variableBindings, directiveRecords);
|
||||
return this._factory(dispatcher, this._pipeRegistry);
|
||||
}
|
||||
|
||||
_createFactoryIfNecessary(bindingRecords:List, variableBindings:List, directiveMementos:List) {
|
||||
_createFactoryIfNecessary(bindingRecords:List, variableBindings:List, directiveRecords:List) {
|
||||
if (isBlank(this._factory)) {
|
||||
var recordBuilder = new ProtoRecordBuilder();
|
||||
ListWrapper.forEach(bindingRecords, (r) => {
|
||||
recordBuilder.addAst(r.ast, r.bindingMemento, r.directiveMemento, variableBindings);
|
||||
ListWrapper.forEach(bindingRecords, (b) => {
|
||||
recordBuilder.addAst(b, variableBindings);
|
||||
});
|
||||
var c = _jitProtoChangeDetectorClassCounter++;
|
||||
var records = coalesce(recordBuilder.records);
|
||||
var typeName = `ChangeDetector${c}`;
|
||||
this._factory = new ChangeDetectorJITGenerator(typeName, this._changeControlStrategy, records,
|
||||
directiveMementos).generate();
|
||||
directiveRecords).generate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,13 +114,13 @@ class ProtoRecordBuilder {
|
||||
this.records = [];
|
||||
}
|
||||
|
||||
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null, variableBindings:List = null) {
|
||||
addAst(b:BindingRecord, variableBindings:List = null) {
|
||||
var last = ListWrapper.last(this.records);
|
||||
if (isPresent(last) && last.directiveMemento == directiveMemento) {
|
||||
if (isPresent(last) && last.bindingRecord.directiveRecord == b.directiveRecord) {
|
||||
last.lastInDirective = false;
|
||||
}
|
||||
|
||||
var pr = _ConvertAstIntoProtoRecords.convert(ast, bindingMemento, directiveMemento, this.records.length, variableBindings);
|
||||
var pr = _ConvertAstIntoProtoRecords.convert(b, this.records.length, variableBindings);
|
||||
if (! ListWrapper.isEmpty(pr)) {
|
||||
var last = ListWrapper.last(pr);
|
||||
last.lastInBinding = true;
|
||||
@ -144,24 +133,22 @@ class ProtoRecordBuilder {
|
||||
|
||||
class _ConvertAstIntoProtoRecords {
|
||||
protoRecords:List;
|
||||
bindingMemento:any;
|
||||
directiveMemento:any;
|
||||
bindingRecord:BindingRecord;
|
||||
variableBindings:List;
|
||||
contextIndex:number;
|
||||
expressionAsString:string;
|
||||
|
||||
constructor(bindingMemento:any, directiveMemento:any, contextIndex:number, expressionAsString:string, variableBindings:List) {
|
||||
constructor(bindingRecord:BindingRecord, contextIndex:number, expressionAsString:string, variableBindings:List) {
|
||||
this.protoRecords = [];
|
||||
this.bindingMemento = bindingMemento;
|
||||
this.directiveMemento = directiveMemento;
|
||||
this.bindingRecord = bindingRecord;
|
||||
this.contextIndex = contextIndex;
|
||||
this.expressionAsString = expressionAsString;
|
||||
this.variableBindings = variableBindings;
|
||||
}
|
||||
|
||||
static convert(ast:AST, bindingMemento:any, directiveMemento:any, contextIndex:number, variableBindings:List) {
|
||||
var c = new _ConvertAstIntoProtoRecords(bindingMemento, directiveMemento, contextIndex, ast.toString(), variableBindings);
|
||||
ast.visit(c);
|
||||
static convert(b:BindingRecord, contextIndex:number, variableBindings:List) {
|
||||
var c = new _ConvertAstIntoProtoRecords(b, contextIndex, b.ast.toString(), variableBindings);
|
||||
b.ast.visit(c);
|
||||
return c.protoRecords;
|
||||
}
|
||||
|
||||
@ -262,7 +249,7 @@ class _ConvertAstIntoProtoRecords {
|
||||
var selfIndex = ++ this.contextIndex;
|
||||
ListWrapper.push(this.protoRecords,
|
||||
new ProtoRecord(type, name, funcOrValue, args, fixedArgs, context, selfIndex,
|
||||
this.bindingMemento, this.directiveMemento, this.expressionAsString, false, false));
|
||||
this.bindingRecord, this.expressionAsString, false, false));
|
||||
return selfIndex;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {List} from 'angular2/src/facade/collection';
|
||||
import {BindingRecord} from './binding_record';
|
||||
|
||||
export const RECORD_TYPE_SELF = 0;
|
||||
export const RECORD_TYPE_CONST = 1;
|
||||
@ -20,8 +21,7 @@ export class ProtoRecord {
|
||||
fixedArgs:List;
|
||||
contextIndex:number;
|
||||
selfIndex:number;
|
||||
bindingMemento:any;
|
||||
directiveMemento:any;
|
||||
bindingRecord:BindingRecord;
|
||||
lastInBinding:boolean;
|
||||
lastInDirective:boolean;
|
||||
expressionAsString:string;
|
||||
@ -33,8 +33,7 @@ export class ProtoRecord {
|
||||
fixedArgs:List,
|
||||
contextIndex:number,
|
||||
selfIndex:number,
|
||||
bindingMemento:any,
|
||||
directiveMemento:any,
|
||||
bindingRecord:BindingRecord,
|
||||
expressionAsString:string,
|
||||
lastInBinding:boolean,
|
||||
lastInDirective:boolean) {
|
||||
@ -46,8 +45,7 @@ export class ProtoRecord {
|
||||
this.fixedArgs = fixedArgs;
|
||||
this.contextIndex = contextIndex;
|
||||
this.selfIndex = selfIndex;
|
||||
this.bindingMemento = bindingMemento;
|
||||
this.directiveMemento = directiveMemento;
|
||||
this.bindingRecord = bindingRecord;
|
||||
this.lastInBinding = lastInBinding;
|
||||
this.lastInDirective = lastInDirective;
|
||||
this.expressionAsString = expressionAsString;
|
||||
|
Reference in New Issue
Block a user