refactor(render): create and store render ProtoViewRef in every app ProtoView

Needed to change Renderer.mergeChildComponentProtoViews to not create
new ProtoViews to be able to deal with cyclic references.

This commit is part of using the new render layer in Angular.
This commit is contained in:
Tobias Bosch
2015-04-07 17:24:09 -07:00
parent d6003ee0ab
commit ca958464c4
16 changed files with 509 additions and 436 deletions

View File

@ -1,4 +1,4 @@
import {Promise} from 'angular2/src/facade/async';
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
import {List, ListWrapper} from 'angular2/src/facade/collection';
import {isBlank, isPresent} from 'angular2/src/facade/lang';
@ -26,10 +26,6 @@ function _wrapView(view:View) {
return new _DirectDomViewRef(view);
}
function _wrapProtoView(protoView:ProtoView) {
return new DirectDomProtoViewRef(protoView);
}
function _collectComponentChildViewRefs(view, target = null) {
if (isBlank(target)) {
target = [];
@ -83,22 +79,22 @@ export class DirectDomRenderer extends api.Renderer {
return this._compiler.compile(template);
}
mergeChildComponentProtoViews(protoViewRef:api.ProtoViewRef, protoViewRefs:List<api.ProtoViewRef>):List<api.ProtoViewRef> {
var protoViews = [];
mergeChildComponentProtoViews(protoViewRef:api.ProtoViewRef, protoViewRefs:List<api.ProtoViewRef>) {
_resolveProtoView(protoViewRef).mergeChildComponentProtoViews(
ListWrapper.map(protoViewRefs, _resolveProtoView),
protoViews
ListWrapper.map(protoViewRefs, _resolveProtoView)
);
return ListWrapper.map(protoViews, _wrapProtoView);
}
createRootProtoView(selectorOrElement):api.ProtoViewRef {
createRootProtoView(selectorOrElement, componentId):Promise<api.ProtoView> {
var element = selectorOrElement; // TODO: select the element if it is not a real element...
var rootProtoViewBuilder = new ProtoViewBuilder(element);
rootProtoViewBuilder.setIsRootView(true);
rootProtoViewBuilder.bindElement(element, 'root element').setComponentId('root');
this._shadowDomStrategy.processElement(null, 'root', element);
return rootProtoViewBuilder.build().render;
var elBinder = rootProtoViewBuilder.bindElement(element, 'root element');
elBinder.setComponentId(componentId);
elBinder.bindDirective(0);
this._shadowDomStrategy.processElement(null, componentId, element);
return PromiseWrapper.resolve(rootProtoViewBuilder.build());
}
createView(protoViewRef:api.ProtoViewRef):List<api.ViewRef> {

View File

@ -1,12 +1,8 @@
import {AST} from 'angular2/change_detection';
import {SetterFn} from 'angular2/src/reflection/types';
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
import {List, ListWrapper} from 'angular2/src/facade/collection';
import * as protoViewModule from './proto_view';
/**
* Note: Code that uses this class assumes that is immutable!
*/
export class ElementBinder {
contentTagSelector: string;
textNodeIndices: List<number>;
@ -39,24 +35,4 @@ export class ElementBinder {
this.distanceToParent = distanceToParent;
this.propertySetters = propertySetters;
}
mergeChildComponentProtoViews(protoViews:List<protoViewModule.ProtoView>, target:List<protoViewModule.ProtoView>):ElementBinder {
var nestedProtoView;
if (isPresent(this.componentId)) {
nestedProtoView = ListWrapper.removeAt(protoViews, 0);
} else if (isPresent(this.nestedProtoView)) {
nestedProtoView = this.nestedProtoView.mergeChildComponentProtoViews(protoViews, target);
}
return new ElementBinder({
parentIndex: this.parentIndex,
textNodeIndices: this.textNodeIndices,
contentTagSelector: this.contentTagSelector,
nestedProtoView: nestedProtoView,
componentId: this.componentId,
eventLocals: this.eventLocals,
eventNames: this.eventNames,
distanceToParent: this.distanceToParent,
propertySetters: this.propertySetters
});
}
}

View File

@ -6,9 +6,6 @@ import {List, Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection
import {ElementBinder} from './element_binder';
import {NG_BINDING_CLASS} from '../util';
/**
* Note: Code that uses this class assumes that is immutable!
*/
export class ProtoView {
element;
elementBinders:List<ElementBinder>;
@ -28,22 +25,14 @@ export class ProtoView {
this.rootBindingOffset = (isPresent(this.element) && DOM.hasClass(this.element, NG_BINDING_CLASS)) ? 1 : 0;
}
mergeChildComponentProtoViews(protoViews:List<ProtoView>, target:List<ProtoView>):ProtoView {
var elementBinders = ListWrapper.createFixedSize(this.elementBinders.length);
mergeChildComponentProtoViews(componentProtoViews:List<ProtoView>) {
var componentProtoViewIndex = 0;
for (var i=0; i<this.elementBinders.length; i++) {
var eb = this.elementBinders[i];
if (isPresent(eb.componentId) || isPresent(eb.nestedProtoView)) {
elementBinders[i] = eb.mergeChildComponentProtoViews(protoViews, target);
} else {
elementBinders[i] = eb;
if (isPresent(eb.componentId)) {
eb.nestedProtoView = componentProtoViews[componentProtoViewIndex];
componentProtoViewIndex++;
}
}
var result = new ProtoView({
elementBinders: elementBinders,
element: this.element,
isRootView: this.isRootView
});
ListWrapper.insert(target, 0, result);
return result
}
}