refactor(view): moved the logic from ProtoView to ProtoViewFactory
This commit is contained in:
parent
0f4a089c32
commit
ce6a2ba836
|
@ -4,9 +4,13 @@ import {IterableChangesFactory} from './pipes/iterable_changes';
|
||||||
import {KeyValueChangesFactory} from './pipes/keyvalue_changes';
|
import {KeyValueChangesFactory} from './pipes/keyvalue_changes';
|
||||||
import {AsyncPipeFactory} from './pipes/async_pipe';
|
import {AsyncPipeFactory} from './pipes/async_pipe';
|
||||||
import {NullPipeFactory} from './pipes/null_pipe';
|
import {NullPipeFactory} from './pipes/null_pipe';
|
||||||
|
import {BindingRecord} from './binding_record';
|
||||||
|
import {DirectiveRecord} from './directive_record';
|
||||||
import {DEFAULT} from './constants';
|
import {DEFAULT} from './constants';
|
||||||
import {ChangeDetection, ProtoChangeDetector} from './interfaces';
|
import {ChangeDetection, ProtoChangeDetector} from './interfaces';
|
||||||
import {Injectable} from 'angular2/di';
|
import {Injectable} from 'angular2/di';
|
||||||
|
import {List} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structural diffing for `Object`s and `Map`s.
|
* Structural diffing for `Object`s and `Map`s.
|
||||||
|
@ -61,8 +65,9 @@ export class DynamicChangeDetection extends ChangeDetection {
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
createProtoChangeDetector(name:string, changeControlStrategy:string = DEFAULT):ProtoChangeDetector{
|
createProtoChangeDetector(name:string, bindingRecords:List<BindingRecord>, variableBindings:List<string>,
|
||||||
return new DynamicProtoChangeDetector(this.registry, changeControlStrategy);
|
directiveRecords:List<DirectiveRecord>, changeControlStrategy:string = DEFAULT):ProtoChangeDetector{
|
||||||
|
return new DynamicProtoChangeDetector(this.registry, bindingRecords, variableBindings, directiveRecords, changeControlStrategy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +87,9 @@ export class JitChangeDetection extends ChangeDetection {
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
createProtoChangeDetector(name:string, changeControlStrategy:string = DEFAULT):ProtoChangeDetector{
|
createProtoChangeDetector(name:string, bindingRecords:List<BindingRecord>, variableBindings:List<string>,
|
||||||
return new JitProtoChangeDetector(this.registry, changeControlStrategy);
|
directiveRecords:List<DirectiveRecord>, changeControlStrategy:string = DEFAULT):ProtoChangeDetector{
|
||||||
|
return new JitProtoChangeDetector(this.registry, bindingRecords, variableBindings, directiveRecords, changeControlStrategy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {DEFAULT} from './constants';
|
||||||
import {BindingRecord} from './binding_record';
|
import {BindingRecord} from './binding_record';
|
||||||
|
|
||||||
export class ProtoChangeDetector {
|
export class ProtoChangeDetector {
|
||||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveRecords:List):ChangeDetector{
|
instantiate(dispatcher:any):ChangeDetector{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@ export class ProtoChangeDetector {
|
||||||
* @exportedAs angular2/change_detection
|
* @exportedAs angular2/change_detection
|
||||||
*/
|
*/
|
||||||
export class ChangeDetection {
|
export class ChangeDetection {
|
||||||
createProtoChangeDetector(name:string, changeControlStrategy:string=DEFAULT):ProtoChangeDetector{
|
createProtoChangeDetector(name:string, bindingRecords:List, variableBindings:List, directiveRecords:List,
|
||||||
|
changeControlStrategy:string=DEFAULT):ProtoChangeDetector{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {DynamicChangeDetector} from './dynamic_change_detector';
|
||||||
import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
|
import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
|
||||||
import {PipeRegistry} from './pipes/pipe_registry';
|
import {PipeRegistry} from './pipes/pipe_registry';
|
||||||
import {BindingRecord} from './binding_record';
|
import {BindingRecord} from './binding_record';
|
||||||
import {DirectiveIndex} from './directive_record';
|
import {DirectiveRecord, DirectiveIndex} from './directive_record';
|
||||||
|
|
||||||
import {coalesce} from './coalesce';
|
import {coalesce} from './coalesce';
|
||||||
|
|
||||||
|
@ -50,25 +50,31 @@ import {
|
||||||
export class DynamicProtoChangeDetector extends ProtoChangeDetector {
|
export class DynamicProtoChangeDetector extends ProtoChangeDetector {
|
||||||
_pipeRegistry:PipeRegistry;
|
_pipeRegistry:PipeRegistry;
|
||||||
_records:List<ProtoRecord>;
|
_records:List<ProtoRecord>;
|
||||||
|
_bindingRecords:List<BindingRecord>;
|
||||||
|
_variableBindings:List<string>;
|
||||||
|
_directiveRecords:List<DirectiveRecord>;
|
||||||
_changeControlStrategy:string;
|
_changeControlStrategy:string;
|
||||||
|
|
||||||
constructor(pipeRegistry:PipeRegistry, changeControlStrategy:string) {
|
constructor(pipeRegistry:PipeRegistry, bindingRecords:List, variableBindings:List, directiveRecords:List, changeControlStrategy:string) {
|
||||||
super();
|
super();
|
||||||
this._pipeRegistry = pipeRegistry;
|
this._pipeRegistry = pipeRegistry;
|
||||||
|
this._bindingRecords = bindingRecords;
|
||||||
|
this._variableBindings = variableBindings;
|
||||||
|
this._directiveRecords = directiveRecords;
|
||||||
this._changeControlStrategy = changeControlStrategy;
|
this._changeControlStrategy = changeControlStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveRecords:List) {
|
instantiate(dispatcher:any) {
|
||||||
this._createRecordsIfNecessary(bindingRecords, variableBindings);
|
this._createRecordsIfNecessary();
|
||||||
return new DynamicChangeDetector(this._changeControlStrategy, dispatcher,
|
return new DynamicChangeDetector(this._changeControlStrategy, dispatcher,
|
||||||
this._pipeRegistry, this._records, directiveRecords);
|
this._pipeRegistry, this._records, this._directiveRecords);
|
||||||
}
|
}
|
||||||
|
|
||||||
_createRecordsIfNecessary(bindingRecords:List, variableBindings:List) {
|
_createRecordsIfNecessary() {
|
||||||
if (isBlank(this._records)) {
|
if (isBlank(this._records)) {
|
||||||
var recordBuilder = new ProtoRecordBuilder();
|
var recordBuilder = new ProtoRecordBuilder();
|
||||||
ListWrapper.forEach(bindingRecords, (b) => {
|
ListWrapper.forEach(this._bindingRecords, (b) => {
|
||||||
recordBuilder.addAst(b, variableBindings);
|
recordBuilder.addAst(b, this._variableBindings);
|
||||||
});
|
});
|
||||||
this._records = coalesce(recordBuilder.records);
|
this._records = coalesce(recordBuilder.records);
|
||||||
}
|
}
|
||||||
|
@ -79,31 +85,37 @@ var _jitProtoChangeDetectorClassCounter:number = 0;
|
||||||
export class JitProtoChangeDetector extends ProtoChangeDetector {
|
export class JitProtoChangeDetector extends ProtoChangeDetector {
|
||||||
_factory:Function;
|
_factory:Function;
|
||||||
_pipeRegistry;
|
_pipeRegistry;
|
||||||
|
_bindingRecords:List<BindingRecord>;
|
||||||
|
_variableBindings:List<string>;
|
||||||
|
_directiveRecords:List<DirectiveRecord>;
|
||||||
_changeControlStrategy:string;
|
_changeControlStrategy:string;
|
||||||
|
|
||||||
constructor(pipeRegistry, changeControlStrategy:string) {
|
constructor(pipeRegistry, bindingRecords:List, variableBindings:List, directiveRecords:List, changeControlStrategy:string) {
|
||||||
super();
|
super();
|
||||||
this._pipeRegistry = pipeRegistry;
|
this._pipeRegistry = pipeRegistry;
|
||||||
this._factory = null;
|
this._factory = null;
|
||||||
|
this._bindingRecords = bindingRecords;
|
||||||
|
this._variableBindings = variableBindings;
|
||||||
|
this._directiveRecords = directiveRecords;
|
||||||
this._changeControlStrategy = changeControlStrategy;
|
this._changeControlStrategy = changeControlStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiate(dispatcher:any, bindingRecords:List, variableBindings:List, directiveRecords:List) {
|
instantiate(dispatcher:any) {
|
||||||
this._createFactoryIfNecessary(bindingRecords, variableBindings, directiveRecords);
|
this._createFactoryIfNecessary();
|
||||||
return this._factory(dispatcher, this._pipeRegistry);
|
return this._factory(dispatcher, this._pipeRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
_createFactoryIfNecessary(bindingRecords:List, variableBindings:List, directiveRecords:List) {
|
_createFactoryIfNecessary() {
|
||||||
if (isBlank(this._factory)) {
|
if (isBlank(this._factory)) {
|
||||||
var recordBuilder = new ProtoRecordBuilder();
|
var recordBuilder = new ProtoRecordBuilder();
|
||||||
ListWrapper.forEach(bindingRecords, (b) => {
|
ListWrapper.forEach(this._bindingRecords, (b) => {
|
||||||
recordBuilder.addAst(b, variableBindings);
|
recordBuilder.addAst(b, this._variableBindings);
|
||||||
});
|
});
|
||||||
var c = _jitProtoChangeDetectorClassCounter++;
|
var c = _jitProtoChangeDetectorClassCounter++;
|
||||||
var records = coalesce(recordBuilder.records);
|
var records = coalesce(recordBuilder.records);
|
||||||
var typeName = `ChangeDetector${c}`;
|
var typeName = `ChangeDetector${c}`;
|
||||||
this._factory = new ChangeDetectorJITGenerator(typeName, this._changeControlStrategy, records,
|
this._factory = new ChangeDetectorJITGenerator(typeName, this._changeControlStrategy, records,
|
||||||
directiveRecords).generate();
|
this._directiveRecords).generate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ export class Compiler {
|
||||||
|
|
||||||
var directiveMetadata = Compiler.buildRenderDirective(componentBinding);
|
var directiveMetadata = Compiler.buildRenderDirective(componentBinding);
|
||||||
return this._renderer.createHostProtoView(directiveMetadata).then( (hostRenderPv) => {
|
return this._renderer.createHostProtoView(directiveMetadata).then( (hostRenderPv) => {
|
||||||
return this._compileNestedProtoViews(null, hostRenderPv, [componentBinding], true);
|
return this._compileNestedProtoViews(null, null, hostRenderPv, [componentBinding], true);
|
||||||
}).then( (appProtoView) => {
|
}).then( (appProtoView) => {
|
||||||
return new ProtoViewRef(appProtoView);
|
return new ProtoViewRef(appProtoView);
|
||||||
});
|
});
|
||||||
|
@ -135,7 +135,7 @@ export class Compiler {
|
||||||
if (isPresent(template.renderer)) {
|
if (isPresent(template.renderer)) {
|
||||||
var directives = [];
|
var directives = [];
|
||||||
pvPromise = this._renderer.createImperativeComponentProtoView(template.renderer).then( (renderPv) => {
|
pvPromise = this._renderer.createImperativeComponentProtoView(template.renderer).then( (renderPv) => {
|
||||||
return this._compileNestedProtoViews(componentBinding, renderPv, directives, true);
|
return this._compileNestedProtoViews(null, componentBinding, renderPv, directives, true);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var directives = ListWrapper.map(
|
var directives = ListWrapper.map(
|
||||||
|
@ -144,7 +144,7 @@ export class Compiler {
|
||||||
);
|
);
|
||||||
var renderTemplate = this._buildRenderTemplate(component, template, directives);
|
var renderTemplate = this._buildRenderTemplate(component, template, directives);
|
||||||
pvPromise = this._renderer.compile(renderTemplate).then( (renderPv) => {
|
pvPromise = this._renderer.compile(renderTemplate).then( (renderPv) => {
|
||||||
return this._compileNestedProtoViews(componentBinding, renderPv, directives, true);
|
return this._compileNestedProtoViews(null, componentBinding, renderPv, directives, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,9 +153,9 @@ export class Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(tbosch): union type return AppProtoView or Promise<AppProtoView>
|
// TODO(tbosch): union type return AppProtoView or Promise<AppProtoView>
|
||||||
_compileNestedProtoViews(componentBinding, renderPv, directives, isComponentRootView) {
|
_compileNestedProtoViews(parentProtoView, componentBinding, renderPv, directives, isComponentRootView) {
|
||||||
var nestedPVPromises = [];
|
var nestedPVPromises = [];
|
||||||
var protoView = this._protoViewFactory.createProtoView(componentBinding, renderPv, directives);
|
var protoView = this._protoViewFactory.createProtoView(parentProtoView, componentBinding, renderPv, directives);
|
||||||
if (isComponentRootView && isPresent(componentBinding)) {
|
if (isComponentRootView && isPresent(componentBinding)) {
|
||||||
// Populate the cache before compiling the nested components,
|
// Populate the cache before compiling the nested components,
|
||||||
// so that components can reference themselves in their template.
|
// so that components can reference themselves in their template.
|
||||||
|
@ -170,15 +170,12 @@ export class Compiler {
|
||||||
var nestedRenderProtoView = renderPv.elementBinders[binderIndex].nestedProtoView;
|
var nestedRenderProtoView = renderPv.elementBinders[binderIndex].nestedProtoView;
|
||||||
var elementBinderDone = (nestedPv) => {
|
var elementBinderDone = (nestedPv) => {
|
||||||
elementBinder.nestedProtoView = nestedPv;
|
elementBinder.nestedProtoView = nestedPv;
|
||||||
// Can't set the parentProtoView for components,
|
|
||||||
// as their AppProtoView might be used in multiple other components.
|
|
||||||
nestedPv.parentProtoView = isPresent(nestedComponent) ? null : protoView;
|
|
||||||
};
|
};
|
||||||
var nestedCall = null;
|
var nestedCall = null;
|
||||||
if (isPresent(nestedComponent)) {
|
if (isPresent(nestedComponent)) {
|
||||||
nestedCall = this._compile(nestedComponent);
|
nestedCall = this._compile(nestedComponent);
|
||||||
} else if (isPresent(nestedRenderProtoView)) {
|
} else if (isPresent(nestedRenderProtoView)) {
|
||||||
nestedCall = this._compileNestedProtoViews(componentBinding, nestedRenderProtoView, directives, false);
|
nestedCall = this._compileNestedProtoViews(protoView, componentBinding, nestedRenderProtoView, directives, false);
|
||||||
}
|
}
|
||||||
if (PromiseWrapper.isPromise(nestedCall)) {
|
if (PromiseWrapper.isPromise(nestedCall)) {
|
||||||
ListWrapper.push(nestedPVPromises, nestedCall.then(elementBinderDone));
|
ListWrapper.push(nestedPVPromises, nestedCall.then(elementBinderDone));
|
||||||
|
|
|
@ -3,13 +3,103 @@ import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
|
||||||
import {ChangeDetection, DirectiveIndex} from 'angular2/change_detection';
|
import {ChangeDetection, DirectiveIndex, BindingRecord, DirectiveRecord, ProtoChangeDetector} from 'angular2/change_detection';
|
||||||
import {Component} from '../annotations_impl/annotations';
|
import {Component} from '../annotations_impl/annotations';
|
||||||
|
|
||||||
import * as renderApi from 'angular2/src/render/api';
|
import * as renderApi from 'angular2/src/render/api';
|
||||||
import {AppProtoView} from './view';
|
import {AppProtoView} from './view';
|
||||||
import {ProtoElementInjector, DirectiveBinding} from './element_injector';
|
import {ProtoElementInjector, DirectiveBinding} from './element_injector';
|
||||||
|
|
||||||
|
|
||||||
|
class BindingRecordsCreator {
|
||||||
|
_directiveRecordsMap;
|
||||||
|
_textNodeIndex:number;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._directiveRecordsMap = MapWrapper.create();
|
||||||
|
this._textNodeIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBindingRecords(elementBinders:List<renderApi.ElementBinder>, sortedDirectives:List<SortedDirectives>):List<BindingRecord> {
|
||||||
|
var bindings = [];
|
||||||
|
|
||||||
|
for (var boundElementIndex = 0; boundElementIndex < elementBinders.length; boundElementIndex++) {
|
||||||
|
var renderElementBinder = elementBinders[boundElementIndex];
|
||||||
|
bindings = ListWrapper.concat(bindings, this._createTextNodeRecords(renderElementBinder));
|
||||||
|
bindings = ListWrapper.concat(bindings, this._createElementPropertyRecords(boundElementIndex, renderElementBinder));
|
||||||
|
bindings = ListWrapper.concat(bindings, this._createDirectiveRecords(boundElementIndex, sortedDirectives[boundElementIndex]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDirectiveRecords(sortedDirectives:List<SortedDirectives>): List {
|
||||||
|
var directiveRecords = [];
|
||||||
|
|
||||||
|
for (var elementIndex = 0; elementIndex < sortedDirectives.length; ++elementIndex) {
|
||||||
|
var dirs = sortedDirectives[elementIndex].directives;
|
||||||
|
for (var dirIndex = 0; dirIndex < dirs.length; ++dirIndex) {
|
||||||
|
ListWrapper.push(directiveRecords, this._getDirectiveRecord(elementIndex, dirIndex, dirs[dirIndex]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return directiveRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createTextNodeRecords(renderElementBinder:renderApi.ElementBinder) {
|
||||||
|
if (isBlank(renderElementBinder.textBindings)) return [];
|
||||||
|
return ListWrapper.map(renderElementBinder.textBindings, b => BindingRecord.createForTextNode(b, this._textNodeIndex++));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createElementPropertyRecords(boundElementIndex:number, renderElementBinder:renderApi.ElementBinder) {
|
||||||
|
var res = [];
|
||||||
|
MapWrapper.forEach(renderElementBinder.propertyBindings, (astWithSource, propertyName) => {
|
||||||
|
ListWrapper.push(res, BindingRecord.createForElement(astWithSource, boundElementIndex, propertyName));
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createDirectiveRecords(boundElementIndex:number, sortedDirectives:SortedDirectives) {
|
||||||
|
var res = [];
|
||||||
|
for (var i = 0; i < sortedDirectives.renderDirectives.length; i++) {
|
||||||
|
var directiveBinder = sortedDirectives.renderDirectives[i];
|
||||||
|
|
||||||
|
// directive properties
|
||||||
|
MapWrapper.forEach(directiveBinder.propertyBindings, (astWithSource, propertyName) => {
|
||||||
|
// TODO: these setters should eventually be created by change detection, to make
|
||||||
|
// it monomorphic!
|
||||||
|
var setter = reflector.setter(propertyName);
|
||||||
|
var directiveRecord = this._getDirectiveRecord(boundElementIndex, i, sortedDirectives.directives[i]);
|
||||||
|
var b = BindingRecord.createForDirective(astWithSource, propertyName, setter, directiveRecord);
|
||||||
|
ListWrapper.push(res, b);
|
||||||
|
});
|
||||||
|
|
||||||
|
// host properties
|
||||||
|
MapWrapper.forEach(directiveBinder.hostPropertyBindings, (astWithSource, propertyName) => {
|
||||||
|
var dirIndex = new DirectiveIndex(boundElementIndex, i);
|
||||||
|
var b = BindingRecord.createForHostProperty(dirIndex, astWithSource, propertyName);
|
||||||
|
ListWrapper.push(res, b);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getDirectiveRecord(boundElementIndex:number, directiveIndex:number, binding:DirectiveBinding): DirectiveRecord {
|
||||||
|
var id = boundElementIndex * 100 + directiveIndex;
|
||||||
|
|
||||||
|
if (!MapWrapper.contains(this._directiveRecordsMap, id)) {
|
||||||
|
var changeDetection = binding.changeDetection;
|
||||||
|
|
||||||
|
MapWrapper.set(this._directiveRecordsMap, id,
|
||||||
|
new DirectiveRecord(new DirectiveIndex(boundElementIndex, directiveIndex),
|
||||||
|
binding.callOnAllChangesDone, binding.callOnChange, changeDetection));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MapWrapper.get(this._directiveRecordsMap, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProtoViewFactory {
|
export class ProtoViewFactory {
|
||||||
_changeDetection:ChangeDetection;
|
_changeDetection:ChangeDetection;
|
||||||
|
@ -18,40 +108,85 @@ export class ProtoViewFactory {
|
||||||
this._changeDetection = changeDetection;
|
this._changeDetection = changeDetection;
|
||||||
}
|
}
|
||||||
|
|
||||||
createProtoView(componentBinding:DirectiveBinding, renderProtoView: renderApi.ProtoViewDto,
|
createProtoView(parentProtoView:AppProtoView, componentBinding:DirectiveBinding,
|
||||||
directives:List<DirectiveBinding>):AppProtoView {
|
renderProtoView: renderApi.ProtoViewDto, directives:List<DirectiveBinding>):AppProtoView {
|
||||||
var protoChangeDetector;
|
|
||||||
if (isBlank(componentBinding)) {
|
var elementBinders = renderProtoView.elementBinders;
|
||||||
protoChangeDetector = this._changeDetection.createProtoChangeDetector('root', null);
|
var sortedDirectives = ListWrapper.map(elementBinders, b => new SortedDirectives(b.directives, directives));
|
||||||
} else {
|
|
||||||
var componentAnnotation:Component = componentBinding.annotation;
|
var variableBindings = this._createVariableBindings(renderProtoView);
|
||||||
protoChangeDetector = this._changeDetection.createProtoChangeDetector(
|
var protoLocals = this._createProtoLocals(renderProtoView);
|
||||||
'dummy', componentAnnotation.changeDetection
|
var variableNames = this._createVariableNames(parentProtoView, protoLocals);
|
||||||
);
|
var protoChangeDetector = this._createProtoChangeDetector(elementBinders, sortedDirectives, componentBinding, variableNames);
|
||||||
}
|
var protoView = new AppProtoView(renderProtoView.render, protoChangeDetector, variableBindings, protoLocals, variableNames);
|
||||||
var protoView = new AppProtoView(renderProtoView.render, protoChangeDetector);
|
|
||||||
|
// TODO: vsavkin refactor to pass element binders into proto view
|
||||||
|
this._createElementBinders(protoView, elementBinders, sortedDirectives)
|
||||||
|
this._bindDirectiveEvents(protoView, sortedDirectives);
|
||||||
|
|
||||||
for (var i=0; i<renderProtoView.elementBinders.length; i++) {
|
|
||||||
var renderElementBinder = renderProtoView.elementBinders[i];
|
|
||||||
var sortedDirectives = new SortedDirectives(renderElementBinder.directives, directives);
|
|
||||||
var parentPeiWithDistance = this._findParentProtoElementInjectorWithDistance(
|
|
||||||
i, protoView.elementBinders, renderProtoView.elementBinders
|
|
||||||
);
|
|
||||||
var protoElementInjector = this._createProtoElementInjector(
|
|
||||||
i, parentPeiWithDistance,
|
|
||||||
sortedDirectives, renderElementBinder
|
|
||||||
);
|
|
||||||
this._createElementBinder(
|
|
||||||
protoView, renderElementBinder, protoElementInjector, sortedDirectives
|
|
||||||
);
|
|
||||||
this._createDirectiveBinders(protoView, i, sortedDirectives);
|
|
||||||
}
|
|
||||||
MapWrapper.forEach(renderProtoView.variableBindings, (mappedName, varName) => {
|
|
||||||
protoView.bindVariable(varName, mappedName);
|
|
||||||
});
|
|
||||||
return protoView;
|
return protoView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_createProtoLocals(renderProtoView):Map {
|
||||||
|
var protoLocals = MapWrapper.create();
|
||||||
|
MapWrapper.forEach(renderProtoView.variableBindings, (mappedName, varName) => {
|
||||||
|
MapWrapper.set(protoLocals, mappedName, null);
|
||||||
|
});
|
||||||
|
return protoLocals;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createVariableBindings(renderProtoView):Map {
|
||||||
|
var variableBindings = MapWrapper.create();
|
||||||
|
MapWrapper.forEach(renderProtoView.variableBindings, (mappedName, varName) => {
|
||||||
|
MapWrapper.set(variableBindings, varName, mappedName);
|
||||||
|
});
|
||||||
|
return variableBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createVariableNames(parentProtoView, protoLocals):List {
|
||||||
|
var variableNames = isPresent(parentProtoView) ? ListWrapper.clone(parentProtoView.variableNames) : [];
|
||||||
|
MapWrapper.forEach(protoLocals, (v, local) => {
|
||||||
|
ListWrapper.push(variableNames, local);
|
||||||
|
});
|
||||||
|
return variableNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createProtoChangeDetector(elementBinders, sortedDirectives, componentBinding, variableNames):ProtoChangeDetector {
|
||||||
|
var bindingRecordsCreator = new BindingRecordsCreator();
|
||||||
|
var bindingRecords = bindingRecordsCreator.getBindingRecords(elementBinders, sortedDirectives);
|
||||||
|
var directiveRecords = bindingRecordsCreator.getDirectiveRecords(sortedDirectives);
|
||||||
|
|
||||||
|
var changeDetection = null;
|
||||||
|
var name = 'root';
|
||||||
|
if (isPresent(componentBinding)) {
|
||||||
|
var componentAnnotation:Component = componentBinding.annotation;
|
||||||
|
changeDetection = componentAnnotation.changeDetection;
|
||||||
|
name = 'dummy';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._changeDetection.createProtoChangeDetector(
|
||||||
|
name,
|
||||||
|
bindingRecords,
|
||||||
|
variableNames,
|
||||||
|
directiveRecords,
|
||||||
|
changeDetection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createElementBinders(protoView, elementBinders, sortedDirectives) {
|
||||||
|
for (var i=0; i<elementBinders.length; i++) {
|
||||||
|
var renderElementBinder = elementBinders[i];
|
||||||
|
var dirs = sortedDirectives[i];
|
||||||
|
|
||||||
|
var parentPeiWithDistance = this._findParentProtoElementInjectorWithDistance(
|
||||||
|
i, protoView.elementBinders, elementBinders);
|
||||||
|
var protoElementInjector = this._createProtoElementInjector(
|
||||||
|
i, parentPeiWithDistance, dirs, renderElementBinder);
|
||||||
|
|
||||||
|
this._createElementBinder(protoView, i, renderElementBinder, protoElementInjector, dirs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_findParentProtoElementInjectorWithDistance(binderIndex, elementBinders, renderElementBinders) {
|
_findParentProtoElementInjectorWithDistance(binderIndex, elementBinders, renderElementBinders) {
|
||||||
var distance = 0;
|
var distance = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -95,7 +230,7 @@ export class ProtoViewFactory {
|
||||||
return protoElementInjector;
|
return protoElementInjector;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createElementBinder(protoView, renderElementBinder, protoElementInjector, sortedDirectives) {
|
_createElementBinder(protoView, boundElementIndex, renderElementBinder, protoElementInjector, sortedDirectives) {
|
||||||
var parent = null;
|
var parent = null;
|
||||||
if (renderElementBinder.parentIndex !== -1) {
|
if (renderElementBinder.parentIndex !== -1) {
|
||||||
parent = protoView.elementBinders[renderElementBinder.parentIndex];
|
parent = protoView.elementBinders[renderElementBinder.parentIndex];
|
||||||
|
@ -106,16 +241,7 @@ export class ProtoViewFactory {
|
||||||
protoElementInjector,
|
protoElementInjector,
|
||||||
sortedDirectives.componentDirective
|
sortedDirectives.componentDirective
|
||||||
);
|
);
|
||||||
// text nodes
|
protoView.bindEvent(renderElementBinder.eventBindings, boundElementIndex, -1);
|
||||||
for (var i=0; i<renderElementBinder.textBindings.length; i++) {
|
|
||||||
protoView.bindTextNode(renderElementBinder.textBindings[i]);
|
|
||||||
}
|
|
||||||
// element properties
|
|
||||||
MapWrapper.forEach(renderElementBinder.propertyBindings, (astWithSource, propertyName) => {
|
|
||||||
protoView.bindElementProperty(astWithSource, propertyName);
|
|
||||||
});
|
|
||||||
// events
|
|
||||||
protoView.bindEvent(renderElementBinder.eventBindings, -1);
|
|
||||||
// variables
|
// variables
|
||||||
// The view's locals needs to have a full set of variable names at construction time
|
// The view's locals needs to have a full set of variable names at construction time
|
||||||
// in order to prevent new variables from being set later in the lifecycle. Since we don't want
|
// in order to prevent new variables from being set later in the lifecycle. Since we don't want
|
||||||
|
@ -127,26 +253,15 @@ export class ProtoViewFactory {
|
||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createDirectiveBinders(protoView, boundElementIndex, sortedDirectives) {
|
_bindDirectiveEvents(protoView, sortedDirectives:List<SortedDirectives>) {
|
||||||
for (var i = 0; i < sortedDirectives.renderDirectives.length; i++) {
|
for (var boundElementIndex = 0; boundElementIndex < sortedDirectives.length; ++boundElementIndex) {
|
||||||
var directiveBinder = sortedDirectives.renderDirectives[i];
|
var dirs = sortedDirectives[boundElementIndex].renderDirectives;
|
||||||
|
for (var i = 0; i < dirs.length; i++) {
|
||||||
// directive properties
|
var directiveBinder = dirs[i];
|
||||||
MapWrapper.forEach(directiveBinder.propertyBindings, (astWithSource, propertyName) => {
|
|
||||||
// TODO: these setters should eventually be created by change detection, to make
|
|
||||||
// it monomorphic!
|
|
||||||
var setter = reflector.setter(propertyName);
|
|
||||||
protoView.bindDirectiveProperty(i, astWithSource, propertyName, setter);
|
|
||||||
});
|
|
||||||
|
|
||||||
// host properties
|
|
||||||
MapWrapper.forEach(directiveBinder.hostPropertyBindings, (astWithSource, propertyName) => {
|
|
||||||
var directiveIndex = new DirectiveIndex(boundElementIndex, i);
|
|
||||||
protoView.bindHostElementProperty(astWithSource, propertyName, directiveIndex);
|
|
||||||
});
|
|
||||||
|
|
||||||
// directive events
|
// directive events
|
||||||
protoView.bindEvent(directiveBinder.eventBindings, i);
|
protoView.bindEvent(directiveBinder.eventBindings, boundElementIndex, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {AST, Locals, ChangeDispatcher, ProtoChangeDetector, ChangeDetector,
|
||||||
|
|
||||||
import {ProtoElementInjector, ElementInjector, PreBuiltObjects, DirectiveBinding} from './element_injector';
|
import {ProtoElementInjector, ElementInjector, PreBuiltObjects, DirectiveBinding} from './element_injector';
|
||||||
import {ElementBinder} from './element_binder';
|
import {ElementBinder} from './element_binder';
|
||||||
import {SetterFn} from 'angular2/src/reflection/types';
|
|
||||||
import {IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||||
import * as renderApi from 'angular2/src/render/api';
|
import * as renderApi from 'angular2/src/render/api';
|
||||||
|
|
||||||
|
@ -164,74 +163,22 @@ export class AppProtoView {
|
||||||
protoChangeDetector:ProtoChangeDetector;
|
protoChangeDetector:ProtoChangeDetector;
|
||||||
variableBindings: Map;
|
variableBindings: Map;
|
||||||
protoLocals:Map;
|
protoLocals:Map;
|
||||||
textNodesWithBindingCount:int;
|
|
||||||
bindings:List;
|
bindings:List;
|
||||||
parentProtoView:AppProtoView;
|
variableNames:List;
|
||||||
_variableBindings:List;
|
|
||||||
|
|
||||||
_directiveRecordsMap:Map;
|
|
||||||
_directiveRecords:List;
|
|
||||||
render:renderApi.RenderProtoViewRef;
|
render:renderApi.RenderProtoViewRef;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
render:renderApi.RenderProtoViewRef,
|
render:renderApi.RenderProtoViewRef,
|
||||||
protoChangeDetector:ProtoChangeDetector) {
|
protoChangeDetector:ProtoChangeDetector,
|
||||||
|
variableBindings:Map,
|
||||||
|
protoLocals:Map,
|
||||||
|
variableNames:List) {
|
||||||
this.render = render;
|
this.render = render;
|
||||||
this.elementBinders = [];
|
this.elementBinders = [];
|
||||||
this.variableBindings = MapWrapper.create();
|
this.variableBindings = variableBindings;
|
||||||
this.protoLocals = MapWrapper.create();
|
this.protoLocals = protoLocals;
|
||||||
|
this.variableNames = variableNames;
|
||||||
this.protoChangeDetector = protoChangeDetector;
|
this.protoChangeDetector = protoChangeDetector;
|
||||||
this.parentProtoView = null;
|
|
||||||
this.textNodesWithBindingCount = 0;
|
|
||||||
this.bindings = [];
|
|
||||||
this._directiveRecordsMap = MapWrapper.create();
|
|
||||||
this._variableBindings = null;
|
|
||||||
this._directiveRecords = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Tobias or Victor. Moving it into the constructor.
|
|
||||||
// this work should be done the constructor of AppProtoView once we separate
|
|
||||||
// AppProtoView and ProtoViewBuilder
|
|
||||||
getVariableBindings(): List {
|
|
||||||
if (isPresent(this._variableBindings)) {
|
|
||||||
return this._variableBindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._variableBindings = isPresent(this.parentProtoView) ?
|
|
||||||
ListWrapper.clone(this.parentProtoView.getVariableBindings()) : [];
|
|
||||||
|
|
||||||
MapWrapper.forEach(this.protoLocals, (v, local) => {
|
|
||||||
ListWrapper.push(this._variableBindings, local);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this._variableBindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Tobias or Victor. Moving it into the constructor.
|
|
||||||
// this work should be done the constructor of ProtoView once we separate
|
|
||||||
// AppProtoView and ProtoViewBuilder
|
|
||||||
getdirectiveRecords(): List {
|
|
||||||
if (isPresent(this._directiveRecords)) {
|
|
||||||
return this._directiveRecords;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._directiveRecords = [];
|
|
||||||
|
|
||||||
for (var injectorIndex = 0; injectorIndex < this.elementBinders.length; ++injectorIndex) {
|
|
||||||
var pei = this.elementBinders[injectorIndex].protoElementInjector;
|
|
||||||
if (isPresent(pei)) {
|
|
||||||
for (var directiveIndex = 0; directiveIndex < pei.numberOfDirectives; ++directiveIndex) {
|
|
||||||
ListWrapper.push(this._directiveRecords, this._getDirectiveRecord(injectorIndex, directiveIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._directiveRecords;
|
|
||||||
}
|
|
||||||
|
|
||||||
bindVariable(contextName:string, templateName:string): void {
|
|
||||||
MapWrapper.set(this.variableBindings, contextName, templateName);
|
|
||||||
MapWrapper.set(this.protoLocals, templateName, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bindElement(parent:ElementBinder, distanceToParent:int, protoElementInjector:ProtoElementInjector,
|
bindElement(parent:ElementBinder, distanceToParent:int, protoElementInjector:ProtoElementInjector,
|
||||||
|
@ -242,32 +189,6 @@ export class AppProtoView {
|
||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a text node binding for the last created ElementBinder via bindElement
|
|
||||||
*/
|
|
||||||
bindTextNode(expression:AST):void {
|
|
||||||
var textNodeIndex = this.textNodesWithBindingCount++;
|
|
||||||
var b = BindingRecord.createForTextNode(expression, textNodeIndex);
|
|
||||||
ListWrapper.push(this.bindings, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an element property binding for the last created ElementBinder via bindElement
|
|
||||||
*/
|
|
||||||
bindElementProperty(expression:AST, setterName:string):void {
|
|
||||||
var elementIndex = this.elementBinders.length-1;
|
|
||||||
var b = BindingRecord.createForElement(expression, elementIndex, setterName);
|
|
||||||
ListWrapper.push(this.bindings, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an host property binding for the last created ElementBinder via bindElement
|
|
||||||
*/
|
|
||||||
bindHostElementProperty(expression:AST, setterName:string, directiveIndex:DirectiveIndex):void {
|
|
||||||
var b = BindingRecord.createForHostProperty(directiveIndex, expression, setterName);
|
|
||||||
ListWrapper.push(this.bindings, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an event binding for the last created ElementBinder via bindElement.
|
* Adds an event binding for the last created ElementBinder via bindElement.
|
||||||
*
|
*
|
||||||
|
@ -281,8 +202,8 @@ export class AppProtoView {
|
||||||
* @param {int} directiveIndex The directive index in the binder or -1 when the event is not bound
|
* @param {int} directiveIndex The directive index in the binder or -1 when the event is not bound
|
||||||
* to a directive
|
* to a directive
|
||||||
*/
|
*/
|
||||||
bindEvent(eventBindings: List<renderApi.EventBinding>, directiveIndex: int = -1): void {
|
bindEvent(eventBindings: List<renderApi.EventBinding>, boundElementIndex:number, directiveIndex: int = -1): void {
|
||||||
var elBinder = this.elementBinders[this.elementBinders.length - 1];
|
var elBinder = this.elementBinders[boundElementIndex];
|
||||||
var events = elBinder.hostListeners;
|
var events = elBinder.hostListeners;
|
||||||
if (isBlank(events)) {
|
if (isBlank(events)) {
|
||||||
events = StringMapWrapper.create();
|
events = StringMapWrapper.create();
|
||||||
|
@ -299,35 +220,4 @@ export class AppProtoView {
|
||||||
MapWrapper.set(event, directiveIndex, eventBinding.source);
|
MapWrapper.set(event, directiveIndex, eventBinding.source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a directive property binding for the last created ElementBinder via bindElement
|
|
||||||
*/
|
|
||||||
bindDirectiveProperty(
|
|
||||||
directiveIndex:number,
|
|
||||||
expression:AST,
|
|
||||||
setterName:string,
|
|
||||||
setter:SetterFn): void {
|
|
||||||
|
|
||||||
var elementIndex = this.elementBinders.length-1;
|
|
||||||
var directiveRecord = this._getDirectiveRecord(elementIndex, directiveIndex);
|
|
||||||
var b = BindingRecord.createForDirective(expression, setterName, setter, directiveRecord);
|
|
||||||
ListWrapper.push(this.bindings, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
_getDirectiveRecord(elementInjectorIndex:number, directiveIndex:number): DirectiveRecord {
|
|
||||||
var id = elementInjectorIndex * 100 + directiveIndex;
|
|
||||||
var protoElementInjector = this.elementBinders[elementInjectorIndex].protoElementInjector;
|
|
||||||
|
|
||||||
if (!MapWrapper.contains(this._directiveRecordsMap, id)) {
|
|
||||||
var binding = protoElementInjector.getDirectiveBindingAtIndex(directiveIndex);
|
|
||||||
var changeDetection = binding.changeDetection;
|
|
||||||
|
|
||||||
MapWrapper.set(this._directiveRecordsMap, id,
|
|
||||||
new DirectiveRecord(new DirectiveIndex(elementInjectorIndex, directiveIndex),
|
|
||||||
binding.callOnAllChangesDone, binding.callOnChange, changeDetection));
|
|
||||||
}
|
|
||||||
|
|
||||||
return MapWrapper.get(this._directiveRecordsMap, id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,7 @@ export class AppViewManagerUtils {
|
||||||
|
|
||||||
createView(protoView:viewModule.AppProtoView, viewManager:avmModule.AppViewManager, renderer:Renderer): viewModule.AppView {
|
createView(protoView:viewModule.AppProtoView, viewManager:avmModule.AppViewManager, renderer:Renderer): viewModule.AppView {
|
||||||
var view = new viewModule.AppView(renderer, protoView, protoView.protoLocals);
|
var view = new viewModule.AppView(renderer, protoView, protoView.protoLocals);
|
||||||
var changeDetector = protoView.protoChangeDetector.instantiate(view, protoView.bindings,
|
var changeDetector = protoView.protoChangeDetector.instantiate(view);
|
||||||
protoView.getVariableBindings(), protoView.getdirectiveRecords());
|
|
||||||
|
|
||||||
var binders = protoView.elementBinders;
|
var binders = protoView.elementBinders;
|
||||||
var elementInjectors = ListWrapper.createFixedSize(binders.length);
|
var elementInjectors = ListWrapper.createFixedSize(binders.length);
|
||||||
|
|
|
@ -16,8 +16,22 @@ import {JitProtoChangeDetector, DynamicProtoChangeDetector} from 'angular2/src/c
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("change detection", () => {
|
describe("change detection", () => {
|
||||||
StringMapWrapper.forEach(
|
StringMapWrapper.forEach(
|
||||||
{ "dynamic": (registry = null, strategy = null) => new DynamicProtoChangeDetector(registry, strategy),
|
{ "dynamic": (bindingRecords, variableBindings = null, directiveRecords = null, registry = null, strategy = null) =>
|
||||||
"JIT": (registry = null, strategy = null) => new JitProtoChangeDetector(registry, strategy)
|
new DynamicProtoChangeDetector(
|
||||||
|
registry,
|
||||||
|
isBlank(bindingRecords) ? [] : bindingRecords,
|
||||||
|
isBlank(variableBindings) ? [] : variableBindings,
|
||||||
|
isBlank(directiveRecords) ? [] : directiveRecords,
|
||||||
|
strategy),
|
||||||
|
|
||||||
|
"JIT": (bindingRecords, variableBindings = null, directiveRecords = null, registry = null, strategy = null) =>
|
||||||
|
new JitProtoChangeDetector(
|
||||||
|
registry,
|
||||||
|
isBlank(bindingRecords) ? [] : bindingRecords,
|
||||||
|
isBlank(variableBindings) ? [] : variableBindings,
|
||||||
|
isBlank(directiveRecords) ? [] : directiveRecords,
|
||||||
|
strategy)
|
||||||
|
|
||||||
}, (createProtoChangeDetector, name) => {
|
}, (createProtoChangeDetector, name) => {
|
||||||
|
|
||||||
if (name == "JIT" && IS_DARTIUM) return;
|
if (name == "JIT" && IS_DARTIUM) return;
|
||||||
|
@ -43,13 +57,13 @@ export function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createChangeDetector(propName:string, exp:string, context = null, locals = null, registry = null) {
|
function createChangeDetector(propName:string, exp:string, context = null, locals = null, registry = null) {
|
||||||
var pcd = createProtoChangeDetector(registry);
|
|
||||||
var dispatcher = new TestDispatcher();
|
var dispatcher = new TestDispatcher();
|
||||||
|
|
||||||
var variableBindings = convertLocalsToVariableBindings(locals);
|
var variableBindings = convertLocalsToVariableBindings(locals);
|
||||||
|
|
||||||
var records = [BindingRecord.createForElement(ast(exp), 0, propName)];
|
var records = [BindingRecord.createForElement(ast(exp), 0, propName)];
|
||||||
var cd = pcd.instantiate(dispatcher, records, variableBindings, []);
|
var pcd = createProtoChangeDetector(records, variableBindings, [], registry);
|
||||||
|
var cd = pcd.instantiate(dispatcher);
|
||||||
cd.hydrate(context, locals, null);
|
cd.hydrate(context, locals, null);
|
||||||
|
|
||||||
return {"changeDetector" : cd, "dispatcher" : dispatcher};
|
return {"changeDetector" : cd, "dispatcher" : dispatcher};
|
||||||
|
@ -61,11 +75,6 @@ export function main() {
|
||||||
return res["dispatcher"].log;
|
return res["dispatcher"].log;
|
||||||
}
|
}
|
||||||
|
|
||||||
function instantiate(protoChangeDetector, dispatcher, bindings, directiveRecords = null) {
|
|
||||||
if (isBlank(directiveRecords)) directiveRecords = [];
|
|
||||||
return protoChangeDetector.instantiate(dispatcher, bindings, null, directiveRecords);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe(`${name} change detection`, () => {
|
describe(`${name} change detection`, () => {
|
||||||
var dispatcher;
|
var dispatcher;
|
||||||
|
|
||||||
|
@ -205,10 +214,10 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support interpolation", () => {
|
it("should support interpolation", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
|
||||||
var ast = parser.parseInterpolation("B{{a}}A", "location");
|
var ast = parser.parseInterpolation("B{{a}}A", "location");
|
||||||
|
var pcd = createProtoChangeDetector([BindingRecord.createForElement(ast, 0, "memo")]);
|
||||||
|
|
||||||
var cd = instantiate(pcd, dispatcher, [BindingRecord.createForElement(ast, 0, "memo")]);
|
var cd = pcd.instantiate(dispatcher);
|
||||||
cd.hydrate(new TestData("value"), null, null);
|
cd.hydrate(new TestData("value"), null, null);
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
@ -267,10 +276,9 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should happen directly, without invoking the dispatcher", () => {
|
it("should happen directly, without invoking the dispatcher", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([updateA("42", dirRecord1)], [], [dirRecord1]);
|
||||||
|
|
||||||
var cd = instantiate(pcd, dispatcher, [updateA("42", dirRecord1)],
|
var cd = pcd.instantiate(dispatcher);
|
||||||
[dirRecord1]);
|
|
||||||
|
|
||||||
cd.hydrate(null, null, dirs([directive1]));
|
cd.hydrate(null, null, dirs([directive1]));
|
||||||
|
|
||||||
|
@ -282,13 +290,13 @@ export function main() {
|
||||||
|
|
||||||
describe("onChange", () => {
|
describe("onChange", () => {
|
||||||
it("should notify the directive when a group of records changes", () => {
|
it("should notify the directive when a group of records changes", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([
|
||||||
|
|
||||||
var cd = instantiate(pcd, dispatcher, [
|
|
||||||
updateA("1", dirRecord1),
|
updateA("1", dirRecord1),
|
||||||
updateB("2", dirRecord1),
|
updateB("2", dirRecord1),
|
||||||
updateA("3", dirRecord2)
|
updateA("3", dirRecord2)
|
||||||
], [dirRecord1, dirRecord2]);
|
], [], [dirRecord1, dirRecord2]);
|
||||||
|
|
||||||
|
var cd = pcd.instantiate(dispatcher);
|
||||||
|
|
||||||
cd.hydrate(null, null, dirs([directive1, directive2]));
|
cd.hydrate(null, null, dirs([directive1, directive2]));
|
||||||
|
|
||||||
|
@ -299,11 +307,11 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not call onChange when callOnChange is false", () => {
|
it("should not call onChange when callOnChange is false", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([
|
||||||
|
|
||||||
var cd = instantiate(pcd, dispatcher, [
|
|
||||||
updateA("1", dirRecordNoCallbacks)
|
updateA("1", dirRecordNoCallbacks)
|
||||||
], [dirRecordNoCallbacks]);
|
], [], [dirRecordNoCallbacks]);
|
||||||
|
|
||||||
|
var cd = pcd.instantiate(dispatcher);
|
||||||
|
|
||||||
cd.hydrate(null, null, dirs([directive1]));
|
cd.hydrate(null, null, dirs([directive1]));
|
||||||
|
|
||||||
|
@ -315,9 +323,9 @@ export function main() {
|
||||||
|
|
||||||
describe("onAllChangesDone", () => {
|
describe("onAllChangesDone", () => {
|
||||||
it("should be called after processing all the children", () => {
|
it("should be called after processing all the children", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([], [], [dirRecord1, dirRecord2]);
|
||||||
|
|
||||||
var cd = instantiate(pcd, dispatcher, [], [dirRecord1, dirRecord2]);
|
var cd = pcd.instantiate(dispatcher);
|
||||||
cd.hydrate(null, null, dirs([directive1, directive2]));
|
cd.hydrate(null, null, dirs([directive1, directive2]));
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
@ -328,11 +336,11 @@ export function main() {
|
||||||
|
|
||||||
|
|
||||||
it("should not be called when onAllChangesDone is false", () => {
|
it("should not be called when onAllChangesDone is false", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([
|
||||||
|
|
||||||
var cd = instantiate(pcd, dispatcher, [
|
|
||||||
updateA("1", dirRecordNoCallbacks)
|
updateA("1", dirRecordNoCallbacks)
|
||||||
], [dirRecordNoCallbacks]);
|
], [], [dirRecordNoCallbacks]);
|
||||||
|
|
||||||
|
var cd = pcd.instantiate(dispatcher);
|
||||||
|
|
||||||
cd.hydrate(null, null, dirs([directive1]));
|
cd.hydrate(null, null, dirs([directive1]));
|
||||||
|
|
||||||
|
@ -342,8 +350,8 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be called in reverse order so the child is always notified before the parent", () => {
|
it("should be called in reverse order so the child is always notified before the parent", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([], [], [dirRecord1, dirRecord2]);
|
||||||
var cd = instantiate(pcd, dispatcher, [], [dirRecord1, dirRecord2]);
|
var cd = pcd.instantiate(dispatcher);
|
||||||
|
|
||||||
var onChangesDoneCalls = [];
|
var onChangesDoneCalls = [];
|
||||||
var td1;
|
var td1;
|
||||||
|
@ -358,13 +366,12 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be called before processing shadow dom children", () => {
|
it("should be called before processing shadow dom children", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([], null, [dirRecord1]);
|
||||||
var shadowDomChildPCD = createProtoChangeDetector();
|
var shadowDomChildPCD = createProtoChangeDetector([updateA("1", dirRecord1)], null, [dirRecord1]);
|
||||||
|
|
||||||
var parent = pcd.instantiate(dispatcher, [], null, [dirRecord1]);
|
var parent = pcd.instantiate(dispatcher);
|
||||||
|
|
||||||
var child = shadowDomChildPCD.instantiate(dispatcher,
|
var child = shadowDomChildPCD.instantiate(dispatcher);
|
||||||
[updateA("1", dirRecord1)], null, [dirRecord1]);
|
|
||||||
parent.addShadowDomChild(child);
|
parent.addShadowDomChild(child);
|
||||||
|
|
||||||
var directiveInShadowDom = new TestDirective();
|
var directiveInShadowDom = new TestDirective();
|
||||||
|
@ -389,8 +396,8 @@ export function main() {
|
||||||
var directive = new TestDirective();
|
var directive = new TestDirective();
|
||||||
directive.a = "aaa";
|
directive.a = "aaa";
|
||||||
|
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([BindingRecord.createForHostProperty(index, ast("a"), "prop")], null, [dirRecord]);
|
||||||
var cd = instantiate(pcd, dispatcher, [BindingRecord.createForHostProperty(index, ast("a"), "prop")], [dirRecord]);
|
var cd = pcd.instantiate(dispatcher);
|
||||||
cd.hydrate(null, null, dirs([directive]));
|
cd.hydrate(null, null, dirs([directive]));
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
@ -401,12 +408,12 @@ export function main() {
|
||||||
|
|
||||||
describe("enforce no new changes", () => {
|
describe("enforce no new changes", () => {
|
||||||
it("should throw when a record gets changed after it has been checked", () => {
|
it("should throw when a record gets changed after it has been checked", () => {
|
||||||
var pcd = createProtoChangeDetector();
|
var pcd = createProtoChangeDetector([
|
||||||
|
|
||||||
var dispatcher = new TestDispatcher();
|
|
||||||
var cd = instantiate(pcd, dispatcher, [
|
|
||||||
BindingRecord.createForElement(ast("a"), 0, "a")
|
BindingRecord.createForElement(ast("a"), 0, "a")
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
var dispatcher = new TestDispatcher();
|
||||||
|
var cd = pcd.instantiate(dispatcher);
|
||||||
cd.hydrate(new TestData('value'), null, null);
|
cd.hydrate(new TestData('value'), null, null);
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
|
@ -487,11 +494,8 @@ export function main() {
|
||||||
var parent, child;
|
var parent, child;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
var protoParent = createProtoChangeDetector();
|
parent = createProtoChangeDetector([]).instantiate(null);
|
||||||
parent = instantiate(protoParent, null, []);
|
child = createProtoChangeDetector([]).instantiate(null);
|
||||||
|
|
||||||
var protoChild = createProtoChangeDetector();
|
|
||||||
child = instantiate(protoChild, null, []);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should add light dom children", () => {
|
it("should add light dom children", () => {
|
||||||
|
@ -526,8 +530,8 @@ export function main() {
|
||||||
|
|
||||||
describe("mode", () => {
|
describe("mode", () => {
|
||||||
it("should set the mode to CHECK_ALWAYS when the default change detection is used", () => {
|
it("should set the mode to CHECK_ALWAYS when the default change detection is used", () => {
|
||||||
var proto = createProtoChangeDetector(null, DEFAULT);
|
var proto = createProtoChangeDetector([], [], [], null, DEFAULT);
|
||||||
var cd = proto.instantiate(null, [], [], []);
|
var cd = proto.instantiate(null);
|
||||||
|
|
||||||
expect(cd.mode).toEqual(null);
|
expect(cd.mode).toEqual(null);
|
||||||
|
|
||||||
|
@ -537,8 +541,8 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set the mode to CHECK_ONCE when the push change detection is used", () => {
|
it("should set the mode to CHECK_ONCE when the push change detection is used", () => {
|
||||||
var proto = createProtoChangeDetector(null, ON_PUSH);
|
var proto = createProtoChangeDetector([], [], [], null, ON_PUSH);
|
||||||
var cd = proto.instantiate(null, [], [], []);
|
var cd = proto.instantiate(null);
|
||||||
cd.hydrate(null, null, null);
|
cd.hydrate(null, null, null);
|
||||||
|
|
||||||
expect(cd.mode).toEqual(CHECK_ONCE);
|
expect(cd.mode).toEqual(CHECK_ONCE);
|
||||||
|
@ -567,7 +571,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should change CHECK_ONCE to CHECKED", () => {
|
it("should change CHECK_ONCE to CHECKED", () => {
|
||||||
var cd = instantiate(createProtoChangeDetector(), null, []);
|
var cd = createProtoChangeDetector([]).instantiate(null);
|
||||||
cd.mode = CHECK_ONCE;
|
cd.mode = CHECK_ONCE;
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
@ -576,7 +580,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not change the CHECK_ALWAYS", () => {
|
it("should not change the CHECK_ALWAYS", () => {
|
||||||
var cd = instantiate(createProtoChangeDetector(), null, []);
|
var cd = createProtoChangeDetector([]).instantiate(null);
|
||||||
cd.mode = CHECK_ALWAYS;
|
cd.mode = CHECK_ALWAYS;
|
||||||
|
|
||||||
cd.detectChanges();
|
cd.detectChanges();
|
||||||
|
@ -591,8 +595,8 @@ export function main() {
|
||||||
var directives;
|
var directives;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
var proto = createProtoChangeDetector(null, ON_PUSH);
|
var proto = createProtoChangeDetector([], [], [], null, ON_PUSH);
|
||||||
checkedDetector = instantiate(proto, null, [], []);
|
checkedDetector = proto.instantiate(null);
|
||||||
checkedDetector.hydrate(null, null, null);
|
checkedDetector.hydrate(null, null, null);
|
||||||
checkedDetector.mode = CHECKED;
|
checkedDetector.mode = CHECKED;
|
||||||
|
|
||||||
|
@ -608,9 +612,9 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set the mode to CHECK_ONCE when a binding is updated", () => {
|
it("should set the mode to CHECK_ONCE when a binding is updated", () => {
|
||||||
var proto = createProtoChangeDetector(null);
|
var proto = createProtoChangeDetector([updateDirWithOnPushRecord], [], [dirRecordWithOnPush]);
|
||||||
|
|
||||||
var cd = instantiate(proto, null, [updateDirWithOnPushRecord], [dirRecordWithOnPush]);
|
var cd = proto.instantiate(null);
|
||||||
cd.hydrate(null, null, directives);
|
cd.hydrate(null, null, directives);
|
||||||
|
|
||||||
expect(checkedDetector.mode).toEqual(CHECKED);
|
expect(checkedDetector.mode).toEqual(CHECKED);
|
||||||
|
@ -625,7 +629,7 @@ export function main() {
|
||||||
|
|
||||||
describe("markPathToRootAsCheckOnce", () => {
|
describe("markPathToRootAsCheckOnce", () => {
|
||||||
function changeDetector(mode, parent) {
|
function changeDetector(mode, parent) {
|
||||||
var cd = instantiate(createProtoChangeDetector(), null, []);
|
var cd = createProtoChangeDetector([]).instantiate(null);
|
||||||
cd.mode = mode;
|
cd.mode = mode;
|
||||||
if (isPresent(parent)) parent.addChild(cd);
|
if (isPresent(parent)) parent.addChild(cd);
|
||||||
return cd;
|
return cd;
|
||||||
|
|
|
@ -283,9 +283,6 @@ export function main() {
|
||||||
compiler.compile(MainComponent).then( (protoViewRef) => {
|
compiler.compile(MainComponent).then( (protoViewRef) => {
|
||||||
expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
|
expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
|
||||||
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView);
|
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView);
|
||||||
// parentProtoView of nested components has to be null as components can
|
|
||||||
// be used by multiple other components.
|
|
||||||
expect(nestedProtoView.parentProtoView).toBe(null);
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
@ -316,11 +313,7 @@ export function main() {
|
||||||
compiler.compile(MainComponent).then( (protoViewRef) => {
|
compiler.compile(MainComponent).then( (protoViewRef) => {
|
||||||
expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
|
expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
|
||||||
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(viewportProtoView);
|
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(viewportProtoView);
|
||||||
expect(viewportProtoView.parentProtoView).toBe(mainProtoView);
|
|
||||||
expect(viewportProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView);
|
expect(viewportProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView);
|
||||||
// parentProtoView of nested components has to be null as components can
|
|
||||||
// be used by multiple other components.
|
|
||||||
expect(nestedProtoView.parentProtoView).toBe(null);
|
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -432,7 +425,7 @@ function createDirectiveBinding(reader, type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createProtoView(elementBinders = null) {
|
function createProtoView(elementBinders = null) {
|
||||||
var pv = new AppProtoView(null, null);
|
var pv = new AppProtoView(null, null, null, null, null);
|
||||||
if (isBlank(elementBinders)) {
|
if (isBlank(elementBinders)) {
|
||||||
elementBinders = [];
|
elementBinders = [];
|
||||||
}
|
}
|
||||||
|
@ -575,7 +568,7 @@ class FakeProtoViewFactory extends ProtoViewFactory {
|
||||||
this._results = results;
|
this._results = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
createProtoView(componentBinding:DirectiveBinding, renderProtoView: renderApi.ProtoViewDto,
|
createProtoView(parentProtoView, componentBinding:DirectiveBinding, renderProtoView: renderApi.ProtoViewDto,
|
||||||
directives:List<DirectiveBinding>):AppProtoView {
|
directives:List<DirectiveBinding>):AppProtoView {
|
||||||
ListWrapper.push(this.requests, [componentBinding, renderProtoView, directives]);
|
ListWrapper.push(this.requests, [componentBinding, renderProtoView, directives]);
|
||||||
return ListWrapper.removeAt(this._results, 0);
|
return ListWrapper.removeAt(this._results, 0);
|
||||||
|
|
|
@ -453,7 +453,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should instantiate directives that depend on pre built objects", function () {
|
it("should instantiate directives that depend on pre built objects", function () {
|
||||||
var protoView = new AppProtoView(null, null);
|
var protoView = new AppProtoView(null, null, null, null, null);
|
||||||
var inj = injector([NeedsProtoViewRef], null, null, new PreBuiltObjects(null, null, protoView));
|
var inj = injector([NeedsProtoViewRef], null, null, new PreBuiltObjects(null, null, protoView));
|
||||||
|
|
||||||
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
|
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
|
||||||
|
@ -700,7 +700,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inject ProtoViewRef", function () {
|
it("should inject ProtoViewRef", function () {
|
||||||
var protoView = new AppProtoView(null, null);
|
var protoView = new AppProtoView(null, null, null, null, null);
|
||||||
var inj = injector([NeedsProtoViewRef], null, null, new PreBuiltObjects(null, null, protoView));
|
var inj = injector([NeedsProtoViewRef], null, null, new PreBuiltObjects(null, null, protoView));
|
||||||
|
|
||||||
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
|
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
xit
|
xit
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
|
||||||
import {TestBed} from 'angular2/src/test_lib/test_bed';
|
import {TestBed} from 'angular2/src/test_lib/test_bed';
|
||||||
|
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
@ -46,6 +47,7 @@ export function main() {
|
||||||
ctx = new MyComp();
|
ctx = new MyComp();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('react to record changes', function() {
|
describe('react to record changes', function() {
|
||||||
it('should consume text node changes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
it('should consume text node changes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
tb.overrideView(MyComp, new View({template: '<div>{{ctxProp}}</div>'}));
|
tb.overrideView(MyComp, new View({template: '<div>{{ctxProp}}</div>'}));
|
||||||
|
|
|
@ -37,7 +37,7 @@ export function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createProtoView() {
|
function createProtoView() {
|
||||||
return new AppProtoView(null, null);
|
return new AppProtoView(null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createView() {
|
function createView() {
|
||||||
|
|
|
@ -80,7 +80,7 @@ export function main() {
|
||||||
staticChildComponentCount++;
|
staticChildComponentCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var res = new AppProtoView(new MockProtoViewRef(staticChildComponentCount), null);
|
var res = new AppProtoView(new MockProtoViewRef(staticChildComponentCount), null, null, null, null);
|
||||||
res.elementBinders = binders;
|
res.elementBinders = binders;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ export function main() {
|
||||||
if (isBlank(binders)) {
|
if (isBlank(binders)) {
|
||||||
binders = [];
|
binders = [];
|
||||||
}
|
}
|
||||||
var res = new AppProtoView(null, null);
|
var res = new AppProtoView(null, null, null, null, null);
|
||||||
res.elementBinders = binders;
|
res.elementBinders = binders;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ export function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createProtoView() {
|
function createProtoView() {
|
||||||
return new AppProtoView(null, null);
|
return new AppProtoView(null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createView(pv) {
|
function createView(pv) {
|
||||||
|
|
|
@ -187,10 +187,8 @@ function setUpChangeDetection(changeDetection:ChangeDetection, iterations, objec
|
||||||
var dispatcher = new DummyDispatcher();
|
var dispatcher = new DummyDispatcher();
|
||||||
var parser = new Parser(new Lexer());
|
var parser = new Parser(new Lexer());
|
||||||
|
|
||||||
var parentProto = changeDetection.createProtoChangeDetector('parent');
|
var parentProto = changeDetection.createProtoChangeDetector('parent', [], [], []);
|
||||||
var parentCd = parentProto.instantiate(dispatcher, [], [], []);
|
var parentCd = parentProto.instantiate(dispatcher);
|
||||||
|
|
||||||
var proto = changeDetection.createProtoChangeDetector("proto");
|
|
||||||
|
|
||||||
var directiveRecord = new DirectiveRecord(new DirectiveIndex(0, 0), false, false, DEFAULT);
|
var directiveRecord = new DirectiveRecord(new DirectiveIndex(0, 0), false, false, DEFAULT);
|
||||||
var bindings = [
|
var bindings = [
|
||||||
|
@ -206,9 +204,11 @@ function setUpChangeDetection(changeDetection:ChangeDetection, iterations, objec
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field9', null), "field9", reflector.setter("field9"), directiveRecord)
|
BindingRecord.createForDirective(parser.parseBinding('field9', null), "field9", reflector.setter("field9"), directiveRecord)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var proto = changeDetection.createProtoChangeDetector("proto", bindings, [], [directiveRecord]);
|
||||||
|
|
||||||
var targetObj = new Obj();
|
var targetObj = new Obj();
|
||||||
for (var i = 0; i < iterations; ++i) {
|
for (var i = 0; i < iterations; ++i) {
|
||||||
var cd = proto.instantiate(dispatcher, bindings, [], [directiveRecord]);
|
var cd = proto.instantiate(dispatcher);
|
||||||
cd.hydrate(object, null, new FakeDirectives(targetObj));
|
cd.hydrate(object, null, new FakeDirectives(targetObj));
|
||||||
parentCd.addChild(cd);
|
parentCd.addChild(cd);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue