refactor(view): change view to pass all bindings to proto change detector at once
This commit is contained in:
+30
-24
@@ -45,36 +45,44 @@ import {
|
||||
|
||||
export class ProtoChangeDetector {
|
||||
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null){}
|
||||
instantiate(dispatcher:any):ChangeDetector{
|
||||
instantiate(dispatcher:any, bindingRecords:List):ChangeDetector{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
_records:List<ProtoRecord>;
|
||||
_recordBuilder:ProtoRecordBuilder;
|
||||
_pipeRegistry:PipeRegistry;
|
||||
_records:List<ProtoRecord>;
|
||||
|
||||
constructor(pipeRegistry:PipeRegistry) {
|
||||
super();
|
||||
this._pipeRegistry = pipeRegistry;
|
||||
this._records = null;
|
||||
this._recordBuilder = new ProtoRecordBuilder();
|
||||
}
|
||||
|
||||
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null) {
|
||||
this._recordBuilder.addAst(ast, bindingMemento, directiveMemento);
|
||||
}
|
||||
|
||||
instantiate(dispatcher:any) {
|
||||
this._createRecordsIfNecessary();
|
||||
instantiate(dispatcher:any, bindingRecords:List) {
|
||||
this._createRecordsIfNecessary(bindingRecords);
|
||||
return new DynamicChangeDetector(dispatcher, this._pipeRegistry, this._records);
|
||||
}
|
||||
|
||||
_createRecordsIfNecessary() {
|
||||
_createRecordsIfNecessary(bindingRecords:List) {
|
||||
if (isBlank(this._records)) {
|
||||
var records = this._recordBuilder.records;
|
||||
this._records = coalesce(records);
|
||||
var recordBuilder = new ProtoRecordBuilder();
|
||||
ListWrapper.forEach(bindingRecords, (r) => {
|
||||
recordBuilder.addAst(r.ast, r.bindingMemento, r.directiveMemento);
|
||||
});
|
||||
this._records = coalesce(recordBuilder.records);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,29 +90,27 @@ export class DynamicProtoChangeDetector extends ProtoChangeDetector {
|
||||
var _jitProtoChangeDetectorClassCounter:number = 0;
|
||||
export class JitProtoChangeDetector extends ProtoChangeDetector {
|
||||
_factory:Function;
|
||||
_recordBuilder:ProtoRecordBuilder;
|
||||
_pipeRegistry;
|
||||
|
||||
constructor(pipeRegistry) {
|
||||
super();
|
||||
this._pipeRegistry = pipeRegistry;
|
||||
this._factory = null;
|
||||
this._recordBuilder = new ProtoRecordBuilder();
|
||||
}
|
||||
|
||||
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null) {
|
||||
this._recordBuilder.addAst(ast, bindingMemento, directiveMemento);
|
||||
}
|
||||
|
||||
instantiate(dispatcher:any) {
|
||||
this._createFactoryIfNecessary();
|
||||
instantiate(dispatcher:any, bindingRecords:List) {
|
||||
this._createFactoryIfNecessary(bindingRecords);
|
||||
return this._factory(dispatcher, this._pipeRegistry);
|
||||
}
|
||||
|
||||
_createFactoryIfNecessary() {
|
||||
_createFactoryIfNecessary(bindingRecords:List) {
|
||||
if (isBlank(this._factory)) {
|
||||
var recordBuilder = new ProtoRecordBuilder();
|
||||
ListWrapper.forEach(bindingRecords, (r) => {
|
||||
recordBuilder.addAst(r.ast, r.bindingMemento, r.directiveMemento);
|
||||
});
|
||||
var c = _jitProtoChangeDetectorClassCounter++;
|
||||
var records = coalesce(this._recordBuilder.records);
|
||||
var records = coalesce(recordBuilder.records);
|
||||
var typeName = `ChangeDetector${c}`;
|
||||
this._factory = new ChangeDetectorJITGenerator(typeName, records).generate();
|
||||
}
|
||||
|
||||
+19
-14
@@ -1,8 +1,8 @@
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
|
||||
import {AST, ContextWithVariableBindings, ChangeDispatcher, ProtoChangeDetector, ChangeDetector, ChangeRecord}
|
||||
from 'angular2/change_detection';
|
||||
import {AST, ContextWithVariableBindings, ChangeDispatcher, ProtoChangeDetector, ChangeDetector,
|
||||
ChangeRecord, BindingRecord} from 'angular2/change_detection';
|
||||
|
||||
import {ProtoElementInjector, ElementInjector, PreBuiltObjects} from './element_injector';
|
||||
import {BindingPropagationConfig} from './binding_propagation_config';
|
||||
@@ -46,10 +46,10 @@ export class View {
|
||||
context: any;
|
||||
contextWithLocals:ContextWithVariableBindings;
|
||||
|
||||
constructor(proto:ProtoView, nodes:List, protoChangeDetector:ProtoChangeDetector, protoContextLocals:Map) {
|
||||
constructor(proto:ProtoView, nodes:List, protoContextLocals:Map) {
|
||||
this.proto = proto;
|
||||
this.nodes = nodes;
|
||||
this.changeDetector = protoChangeDetector.instantiate(this);
|
||||
this.changeDetector = null;
|
||||
this.elementInjectors = null;
|
||||
this.rootElementInjectors = null;
|
||||
this.textNodes = null;
|
||||
@@ -63,8 +63,9 @@ export class View {
|
||||
: null;
|
||||
}
|
||||
|
||||
init(elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List,
|
||||
init(changeDetector:ChangeDetector, elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List,
|
||||
viewContainers:List, preBuiltObjects:List, componentChildViews:List) {
|
||||
this.changeDetector = changeDetector;
|
||||
this.elementInjectors = elementInjectors;
|
||||
this.rootElementInjectors = rootElementInjectors;
|
||||
this.textNodes = textNodes;
|
||||
@@ -294,12 +295,13 @@ export class ProtoView {
|
||||
_viewPool: ViewPool;
|
||||
stylePromises: List<Promise>;
|
||||
// List<Map<eventName, handler>>, indexed by binder index
|
||||
eventHandlers: List;
|
||||
eventHandlers:List;
|
||||
bindingRecords:List;
|
||||
|
||||
constructor(
|
||||
template,
|
||||
protoChangeDetector:ProtoChangeDetector,
|
||||
shadowDomStrategy: ShadowDomStrategy) {
|
||||
shadowDomStrategy:ShadowDomStrategy) {
|
||||
this.element = template;
|
||||
this.elementBinders = [];
|
||||
this.variableBindings = MapWrapper.create();
|
||||
@@ -315,6 +317,7 @@ export class ProtoView {
|
||||
this._viewPool = new ViewPool(VIEW_POOL_CAPACITY);
|
||||
this.stylePromises = [];
|
||||
this.eventHandlers = [];
|
||||
this.bindingRecords = [];
|
||||
}
|
||||
|
||||
// TODO(rado): hostElementInjector should be moved to hydrate phase.
|
||||
@@ -357,7 +360,9 @@ export class ProtoView {
|
||||
viewNodes = [rootElementClone];
|
||||
}
|
||||
|
||||
var view = new View(this, viewNodes, this.protoChangeDetector, this.protoContextLocals);
|
||||
var view = new View(this, viewNodes, this.protoContextLocals);
|
||||
var changeDetector = this.protoChangeDetector.instantiate(view, this.bindingRecords);
|
||||
|
||||
var binders = this.elementBinders;
|
||||
var elementInjectors = ListWrapper.createFixedSize(binders.length);
|
||||
var eventHandlers = ListWrapper.createFixedSize(binders.length);
|
||||
@@ -413,12 +418,12 @@ export class ProtoView {
|
||||
if (isPresent(binder.componentDirective)) {
|
||||
var strategy = this.shadowDomStrategy;
|
||||
var childView = binder.nestedProtoView.instantiate(elementInjector, eventManager);
|
||||
view.changeDetector.addChild(childView.changeDetector);
|
||||
changeDetector.addChild(childView.changeDetector);
|
||||
|
||||
lightDom = strategy.constructLightDom(view, childView, element);
|
||||
strategy.attachTemplate(element, childView);
|
||||
|
||||
bindingPropagationConfig = new BindingPropagationConfig(view.changeDetector);
|
||||
bindingPropagationConfig = new BindingPropagationConfig(changeDetector);
|
||||
|
||||
ListWrapper.push(componentChildViews, childView);
|
||||
}
|
||||
@@ -454,7 +459,7 @@ export class ProtoView {
|
||||
|
||||
this.eventHandlers = eventHandlers;
|
||||
|
||||
view.init(elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
|
||||
view.init(changeDetector, elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
|
||||
viewContainers, preBuiltObjects, componentChildViews);
|
||||
|
||||
return view;
|
||||
@@ -519,7 +524,7 @@ export class ProtoView {
|
||||
}
|
||||
ListWrapper.push(elBinder.textNodeIndices, indexInParent);
|
||||
var memento = this.textNodesWithBindingCount++;
|
||||
this.protoChangeDetector.addAst(expression, memento);
|
||||
ListWrapper.push(this.bindingRecords, new BindingRecord(expression, memento, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,7 +537,7 @@ export class ProtoView {
|
||||
this.elementsWithBindingCount++;
|
||||
}
|
||||
var memento = new ElementBindingMemento(this.elementsWithBindingCount-1, setterName, setter);
|
||||
this.protoChangeDetector.addAst(expression, memento);
|
||||
ListWrapper.push(this.bindingRecords, new BindingRecord(expression, memento, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -579,7 +584,7 @@ export class ProtoView {
|
||||
setter
|
||||
);
|
||||
var directiveMemento = DirectiveMemento.get(bindingMemento);
|
||||
this.protoChangeDetector.addAst(expression, bindingMemento, directiveMemento);
|
||||
ListWrapper.push(this.bindingRecords, new BindingRecord(expression, bindingMemento, directiveMemento));
|
||||
}
|
||||
|
||||
// Create a rootView as if the compiler encountered <rootcmp></rootcmp>,
|
||||
|
||||
Reference in New Issue
Block a user