feat(change_detection): do not reparse AST when using generated detectors

This commit is contained in:
vsavkin
2015-08-19 11:26:45 -07:00
parent b986c54079
commit d2d0715568
31 changed files with 423 additions and 279 deletions

View File

@ -211,12 +211,10 @@ export class ProtoViewFactory {
var nestedPvVariableBindings = _collectNestedProtoViewsVariableBindings(nestedPvsWithIndex);
var nestedPvVariableNames = _collectNestedProtoViewsVariableNames(nestedPvsWithIndex);
var changeDetectorDefs =
_getChangeDetectorDefinitions(hostComponentBinding.metadata, nestedPvsWithIndex,
var protoChangeDetectors =
this._getProtoChangeDetectors(hostComponentBinding, nestedPvsWithIndex,
nestedPvVariableNames, allRenderDirectiveMetadata);
var protoChangeDetectors = ListWrapper.map(
changeDetectorDefs,
changeDetectorDef => this._changeDetection.createProtoChangeDetector(changeDetectorDef));
var appProtoViews = ListWrapper.createFixedSize(nestedPvsWithIndex.length);
ListWrapper.forEach(nestedPvsWithIndex, (pvWithIndex: RenderProtoViewWithIndex) => {
var appProtoView =
@ -230,6 +228,24 @@ export class ProtoViewFactory {
});
return appProtoViews;
}
private _getProtoChangeDetectors(hostComponentBinding: DirectiveBinding,
nestedPvsWithIndex: RenderProtoViewWithIndex[],
nestedPvVariableNames: string[][],
allRenderDirectiveMetadata: any[]): ProtoChangeDetector[] {
if (this._changeDetection.generateDetectors) {
var changeDetectorDefs =
_getChangeDetectorDefinitions(hostComponentBinding.metadata, nestedPvsWithIndex,
nestedPvVariableNames, allRenderDirectiveMetadata);
return changeDetectorDefs.map(changeDetectorDef =>
this._changeDetection.getProtoChangeDetector(
changeDetectorDef.id, changeDetectorDef));
} else {
var changeDetectorIds =
_getChangeDetectorDefinitionIds(hostComponentBinding.metadata, nestedPvsWithIndex);
return changeDetectorIds.map(id => this._changeDetection.getProtoChangeDetector(id, null));
}
}
}
/**
@ -280,22 +296,35 @@ function _getChangeDetectorDefinitions(
var directiveRecords =
bindingRecordsCreator.getDirectiveRecords(elementBinders, allRenderDirectiveMetadata);
var strategyName = DEFAULT;
var typeString;
if (pvWithIndex.renderProtoView.type === ViewType.COMPONENT) {
strategyName = hostComponentMetadata.changeDetection;
typeString = 'comp';
} else if (pvWithIndex.renderProtoView.type === ViewType.HOST) {
typeString = 'host';
} else {
typeString = 'embedded';
}
var id = `${hostComponentMetadata.id}_${typeString}_${pvWithIndex.index}`;
var id = _protoViewId(hostComponentMetadata, pvWithIndex);
var variableNames = nestedPvVariableNames[pvWithIndex.index];
return new ChangeDetectorDefinition(id, strategyName, variableNames, propBindingRecords,
eventBindingRecords, directiveRecords, assertionsEnabled());
});
}
function _getChangeDetectorDefinitionIds(hostComponentMetadata: RenderDirectiveMetadata,
nestedPvsWithIndex: List<RenderProtoViewWithIndex>):
string[] {
return nestedPvsWithIndex.map(pvWithIndex => _protoViewId(hostComponentMetadata, pvWithIndex));
}
function _protoViewId(hostComponentMetadata: RenderDirectiveMetadata,
pvWithIndex: RenderProtoViewWithIndex): string {
var typeString;
if (pvWithIndex.renderProtoView.type === ViewType.COMPONENT) {
typeString = 'comp';
} else if (pvWithIndex.renderProtoView.type === ViewType.HOST) {
typeString = 'host';
} else {
typeString = 'embedded';
}
return `${hostComponentMetadata.id}_${typeString}_${pvWithIndex.index}`;
}
function _createAppProtoView(
renderProtoView: ProtoViewDto, protoChangeDetector: ProtoChangeDetector,
variableBindings: Map<string, string>, allDirectives: List<DirectiveBinding>,

View File

@ -8,12 +8,12 @@ import {
} from 'angular2/src/facade/collection';
import {
AST,
BindingRecord,
ChangeDetector,
ChangeDetectorRef,
ChangeDispatcher,
DirectiveIndex,
DirectiveRecord,
BindingTarget,
Locals,
ProtoChangeDetector
} from 'angular2/src/change_detection/change_detection';
@ -171,7 +171,7 @@ export class AppView implements ChangeDispatcher, RenderEventDispatcher {
}
// dispatch to element injector or text nodes based on context
notifyOnBinding(b: BindingRecord, currentValue: any): void {
notifyOnBinding(b: BindingTarget, currentValue: any): void {
if (b.isTextNode()) {
this.renderer.setText(
this.render, this.mainMergeMapping.renderTextIndices[b.elementIndex + this.textOffset],
@ -179,14 +179,14 @@ export class AppView implements ChangeDispatcher, RenderEventDispatcher {
} else {
var elementRef = this.elementRefs[this.elementOffset + b.elementIndex];
if (b.isElementProperty()) {
this.renderer.setElementProperty(elementRef, b.propertyName, currentValue);
this.renderer.setElementProperty(elementRef, b.name, currentValue);
} else if (b.isElementAttribute()) {
this.renderer.setElementAttribute(elementRef, b.propertyName, currentValue);
this.renderer.setElementAttribute(elementRef, b.name, currentValue);
} else if (b.isElementClass()) {
this.renderer.setElementClass(elementRef, b.propertyName, currentValue);
this.renderer.setElementClass(elementRef, b.name, currentValue);
} else if (b.isElementStyle()) {
var unit = isPresent(b.propertyUnit) ? b.propertyUnit : '';
this.renderer.setElementStyle(elementRef, b.propertyName, `${currentValue}${unit}`);
var unit = isPresent(b.unit) ? b.unit : '';
this.renderer.setElementStyle(elementRef, b.name, `${currentValue}${unit}`);
} else {
throw new BaseException('Unsupported directive record');
}