Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/angular2/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export {AppViewManager} from 'angular2/src/core/compiler/view_manager';
export {IQueryList} from 'angular2/src/core/compiler/interface_query';
export {QueryList} from 'angular2/src/core/compiler/query_list';
export {ElementRef} from 'angular2/src/core/compiler/element_ref';
export {TemplateRef} from 'angular2/src/core/compiler/template_ref';
export {RenderElementRef} from 'angular2/src/render/api';
export {ViewRef, ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
export {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
Expand Down
8 changes: 4 additions & 4 deletions modules/angular2/src/core/annotations_impl/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,12 @@ import {DEFAULT} from 'angular2/change_detection';
* })
* export class Unless {
* viewContainer: ViewContainerRef;
* protoViewRef: ProtoViewRef;
* templateRef: TemplateRef;
* prevCondition: boolean;
*
* constructor(viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef) {
* constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef) {
* this.viewContainer = viewContainer;
* this.protoViewRef = protoViewRef;
* this.templateRef = templateRef;
* this.prevCondition = null;
* }
*
Expand All @@ -375,7 +375,7 @@ import {DEFAULT} from 'angular2/change_detection';
* this.viewContainer.clear();
* } else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
* this.prevCondition = false;
* this.viewContainer.create(this.protoViewRef);
* this.viewContainer.create(this.templateRef);
* }
* }
* }
Expand Down
4 changes: 2 additions & 2 deletions modules/angular2/src/core/compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ export class Compiler {
return this._compileNestedProtoViews(hostRenderPv, protoView, componentType);
});
}
return hostPvPromise.then(hostAppProtoView => this._mergeCyclicEmbeddedProtoViews().then(
_ => new ProtoViewRef(hostAppProtoView)));
return hostPvPromise.then(
hostAppProtoView => this._mergeCyclicEmbeddedProtoViews().then(_ => hostAppProtoView.ref));
}

private _compile(componentBinding: DirectiveBinding): Promise<AppProtoView>| AppProtoView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class DynamicComponentLoader {
.then(hostProtoViewRef => {
var viewContainer = this._viewManager.getViewContainer(location);
var hostViewRef =
viewContainer.create(hostProtoViewRef, viewContainer.length, null, bindings);
viewContainer.createHostView(hostProtoViewRef, viewContainer.length, bindings);
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);

Expand Down
14 changes: 7 additions & 7 deletions modules/angular2/src/core/compiler/element_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import * as viewModule from './view';
import * as avmModule from './view_manager';
import {ViewContainerRef} from './view_container_ref';
import {ElementRef} from './element_ref';
import {ProtoViewRef, ViewRef} from './view_ref';
import {TemplateRef} from './template_ref';
import {Directive, Component, LifecycleEvent} from 'angular2/src/core/annotations_impl/annotations';
import {hasLifecycleHook} from './directive_lifecycle_reflector';
import {ChangeDetector, ChangeDetectorRef, Pipes} from 'angular2/change_detection';
Expand All @@ -52,15 +52,15 @@ var _staticKeys;

export class StaticKeys {
viewManagerId: number;
protoViewId: number;
templateRefId: number;
viewContainerId: number;
changeDetectorRefId: number;
elementRefId: number;
pipesKey: Key;

constructor() {
this.viewManagerId = Key.get(avmModule.AppViewManager).id;
this.protoViewId = Key.get(ProtoViewRef).id;
this.templateRefId = Key.get(TemplateRef).id;
this.viewContainerId = Key.get(ViewContainerRef).id;
this.changeDetectorRefId = Key.get(ChangeDetectorRef).id;
this.elementRefId = Key.get(ElementRef).id;
Expand Down Expand Up @@ -278,7 +278,7 @@ export class DirectiveBinding extends ResolvedBinding {
// TODO(rado): benchmark and consider rolling in as ElementInjector fields.
export class PreBuiltObjects {
constructor(public viewManager: avmModule.AppViewManager, public view: viewModule.AppView,
public elementRef: ElementRef, public protoView: viewModule.AppProtoView) {}
public elementRef: ElementRef, public templateRef: TemplateRef) {}
}

export class EventEmitterAccessor {
Expand Down Expand Up @@ -622,15 +622,15 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
return this.getViewContainerRef();
}

if (dirDep.key.id === StaticKeys.instance().protoViewId) {
if (isBlank(this._preBuiltObjects.protoView)) {
if (dirDep.key.id === StaticKeys.instance().templateRefId) {
if (isBlank(this._preBuiltObjects.templateRef)) {
if (dirDep.optional) {
return null;
}

throw new NoBindingError(dirDep.key);
}
return new ProtoViewRef(this._preBuiltObjects.protoView);
return this._preBuiltObjects.templateRef;
}

return undefinedValue;
Expand Down
32 changes: 32 additions & 0 deletions modules/angular2/src/core/compiler/template_ref.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {internalView, ProtoViewRef} from './view_ref';
import {ElementRef} from './element_ref';
import * as viewModule from './view';

/**
* Reference to a template within a component.
*
* Represents an opaque reference to the underlying template that can
* be instantiated using the {@Link ViewContainerRef}.
*/
export class TemplateRef {
/**
* The location of the template
*/
elementRef: ElementRef;

constructor(elementRef: ElementRef) { this.elementRef = elementRef; }

private _getProtoView(): viewModule.AppProtoView {
var parentView = internalView(this.elementRef.parentView);
return parentView.proto
.elementBinders[this.elementRef.boundElementIndex - parentView.elementOffset]
.nestedProtoView;
}

get protoViewRef(): ProtoViewRef { return this._getProtoView().ref; }

/**
* Whether this template has a local variable with the given name
*/
hasLocal(name: string): boolean { return this._getProtoView().protoLocals.has(name); }
}
4 changes: 3 additions & 1 deletion modules/angular2/src/core/compiler/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {ElementBinder} from './element_binder';
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
import * as renderApi from 'angular2/src/render/api';
import {RenderEventDispatcher} from 'angular2/src/render/api';
import {ViewRef, internalView} from './view_ref';
import {ViewRef, ProtoViewRef, internalView} from './view_ref';
import {ElementRef} from './element_ref';

export class AppProtoViewMergeMapping {
Expand Down Expand Up @@ -256,10 +256,12 @@ export class AppProtoView {
elementBinders: List<ElementBinder> = [];
protoLocals: Map<string, any> = new Map();
mergeMapping: AppProtoViewMergeMapping;
ref: ProtoViewRef;

constructor(public type: renderApi.ViewType, public protoChangeDetector: ProtoChangeDetector,
public variableBindings: Map<string, string>,
public variableLocations: Map<string, number>, public textBindingCount: number) {
this.ref = new ProtoViewRef(this);
if (isPresent(variableBindings)) {
MapWrapper.forEach(variableBindings,
(templateName, _) => { this.protoLocals.set(templateName, null); });
Expand Down
14 changes: 10 additions & 4 deletions modules/angular2/src/core/compiler/view_container_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as avmModule from './view_manager';
import * as viewModule from './view';

import {ElementRef} from './element_ref';
import {TemplateRef} from './template_ref';
import {ViewRef, ProtoViewRef, internalView} from './view_ref';

export class ViewContainerRef {
Expand All @@ -28,11 +29,16 @@ export class ViewContainerRef {

// TODO(rado): profile and decide whether bounds checks should be added
// to the methods below.
create(protoViewRef: ProtoViewRef = null, atIndex: number = -1, context: ElementRef = null,
bindings: ResolvedBinding[] = null): ViewRef {
createEmbeddedView(templateRef: TemplateRef, atIndex: number = -1): ViewRef {
if (atIndex == -1) atIndex = this.length;
return this.viewManager.createViewInContainer(this.element, atIndex, protoViewRef, context,
bindings);
return this.viewManager.createEmbeddedViewInContainer(this.element, atIndex, templateRef);
}

createHostView(protoViewRef: ProtoViewRef = null, atIndex: number = -1,
dynamicallyCreatedBindings: ResolvedBinding[] = null): ViewRef {
if (atIndex == -1) atIndex = this.length;
return this.viewManager.createHostViewInContainer(this.element, atIndex, protoViewRef,
dynamicallyCreatedBindings);
}

insert(viewRef: ViewRef, atIndex: number = -1): ViewRef {
Expand Down
57 changes: 41 additions & 16 deletions modules/angular2/src/core/compiler/view_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as viewModule from './view';
import {ElementRef} from './element_ref';
import {ProtoViewRef, ViewRef, internalView, internalProtoView} from './view_ref';
import {ViewContainerRef} from './view_container_ref';
import {TemplateRef} from './template_ref';
import {
Renderer,
RenderViewRef,
Expand Down Expand Up @@ -39,9 +40,11 @@ export class AppViewManager {
/**
* Return the first child element of the host element view.
*/
// TODO(misko): remove https://github.com/angular/angular/issues/2891
getHostElement(hostViewRef: ViewRef): ElementRef {
var hostView = internalView(hostViewRef);
if (hostView.proto.type !== ViewType.HOST) {
throw new BaseException('This operation is only allowed on host views');
}
return hostView.elementRefs[hostView.elementOffset];
}

Expand Down Expand Up @@ -170,22 +173,42 @@ export class AppViewManager {
*
* See {@link AppViewManager#destroyViewInContainer}.
*/
createViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
protoViewRef: ProtoViewRef, context: ElementRef = null,
bindings: ResolvedBinding[] = null): ViewRef {
createEmbeddedViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
templateRef: TemplateRef): ViewRef {
var protoView = internalProtoView(templateRef.protoViewRef);
if (protoView.type !== ViewType.EMBEDDED) {
throw new BaseException('This method can only be called with embedded ProtoViews!');
}
return this._createViewInContainer(viewContainerLocation, atIndex, protoView,
templateRef.elementRef, null);
}

/**
*
* See {@link AppViewManager#destroyViewInContainer}.
*/
createHostViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
protoViewRef: ProtoViewRef,
imperativelyCreatedInjector: ResolvedBinding[]): ViewRef {
var protoView = internalProtoView(protoViewRef);
var parentView = internalView(viewContainerLocation.parentView);
var boundElementIndex = viewContainerLocation.boundElementIndex;
var contextView = null;
var contextBoundElementIndex = null;
if (isPresent(context)) {
contextView = internalView(context.parentView);
contextBoundElementIndex = context.boundElementIndex;
} else {
contextView = parentView;
contextBoundElementIndex = boundElementIndex;
if (protoView.type !== ViewType.HOST) {
throw new BaseException('This method can only be called with host ProtoViews!');
}
return this._createViewInContainer(viewContainerLocation, atIndex, protoView,
viewContainerLocation, imperativelyCreatedInjector);
}

/**
*
* See {@link AppViewManager#destroyViewInContainer}.
*/
_createViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
protoView: viewModule.AppProtoView, context: ElementRef,
imperativelyCreatedInjector: ResolvedBinding[]): ViewRef {
var parentView = internalView(viewContainerLocation.parentView);
var boundElementIndex = viewContainerLocation.boundElementIndex;
var contextView = internalView(context.parentView);
var contextBoundElementIndex = context.boundElementIndex;
var embeddedFragmentView = contextView.getNestedView(contextBoundElementIndex);
var view;
if (protoView.type === ViewType.EMBEDDED && isPresent(embeddedFragmentView) &&
Expand All @@ -194,7 +217,8 @@ export class AppViewManager {
view = embeddedFragmentView;
this._attachRenderView(parentView, boundElementIndex, atIndex, view);
} else {
// Case 2: instantiate another copy of the template. This is a separate case
// Case 2: instantiate another copy of the template or a host ProtoView.
// This is a separate case
// as we only inline one copy of the template into the parent view.
view = this._createPooledView(protoView);
this._attachRenderView(parentView, boundElementIndex, atIndex, view);
Expand All @@ -203,7 +227,8 @@ export class AppViewManager {
this._utils.attachViewInContainer(parentView, boundElementIndex, contextView,
contextBoundElementIndex, atIndex, view);
this._utils.hydrateViewInContainer(parentView, boundElementIndex, contextView,
contextBoundElementIndex, atIndex, bindings);
contextBoundElementIndex, atIndex,
imperativelyCreatedInjector);
return view.ref;
}

Expand Down
11 changes: 7 additions & 4 deletions modules/angular2/src/core/compiler/view_manager_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as viewModule from './view';
import {internalView} from './view_ref';
import * as avmModule from './view_manager';
import {ElementRef} from './element_ref';
import {TemplateRef} from './template_ref';
import {Renderer, RenderViewWithFragments} from 'angular2/src/render/api';
import {Locals} from 'angular2/change_detection';
import {RenderViewRef, RenderFragmentRef, ViewType} from 'angular2/src/render/api';
Expand Down Expand Up @@ -83,9 +84,9 @@ export class AppViewManagerUtils {

// preBuiltObjects
if (isPresent(elementInjector)) {
var embeddedProtoView = binder.hasEmbeddedProtoView() ? binder.nestedProtoView : null;
var templateRef = binder.hasEmbeddedProtoView() ? new TemplateRef(el) : null;
preBuiltObjects[boundElementIndex] =
new eli.PreBuiltObjects(viewManager, currentView, el, embeddedProtoView);
new eli.PreBuiltObjects(viewManager, currentView, el, templateRef);
}
}
currentView.init(protoView.protoChangeDetector.instantiate(currentView), elementInjectors,
Expand Down Expand Up @@ -155,7 +156,7 @@ export class AppViewManagerUtils {

hydrateViewInContainer(parentView: viewModule.AppView, boundElementIndex: number,
contextView: viewModule.AppView, contextBoundElementIndex: number,
atIndex: number, bindings: ResolvedBinding[]) {
atIndex: number, imperativelyCreatedBindings: ResolvedBinding[]) {
if (isBlank(contextView)) {
contextView = parentView;
contextBoundElementIndex = boundElementIndex;
Expand All @@ -164,7 +165,9 @@ export class AppViewManagerUtils {
var view = viewContainer.views[atIndex];
var elementInjector = contextView.elementInjectors[contextBoundElementIndex];

var injector = isPresent(bindings) ? Injector.fromResolvedBindings(bindings) : null;
var injector = isPresent(imperativelyCreatedBindings) ?
Injector.fromResolvedBindings(imperativelyCreatedBindings) :
null;
this._hydrateView(view, injector, elementInjector.getHost(), contextView.context,
contextView.locals);
}
Expand Down
10 changes: 5 additions & 5 deletions modules/angular2/src/directives/ng_for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Directive} from 'angular2/annotations';
import {
ViewContainerRef,
ViewRef,
ProtoViewRef,
TemplateRef,
Pipes,
LifecycleEvent,
Pipe,
Expand Down Expand Up @@ -46,7 +46,7 @@ export class NgFor {
_ngForOf: any;
_pipe: Pipe;

constructor(private viewContainer: ViewContainerRef, private protoViewRef: ProtoViewRef,
constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef,
private pipes: Pipes, private cdr: ChangeDetectorRef) {}

set ngForOf(value: any) {
Expand Down Expand Up @@ -79,7 +79,7 @@ export class NgFor {
changes.forEachAddedItem((addedRecord) =>
insertTuples.push(new RecordViewTuple(addedRecord, null)));

NgFor.bulkInsert(insertTuples, this.viewContainer, this.protoViewRef);
NgFor.bulkInsert(insertTuples, this.viewContainer, this.templateRef);

for (var i = 0; i < insertTuples.length; i++) {
this._perViewChange(insertTuples[i].view, insertTuples[i].record);
Expand Down Expand Up @@ -109,14 +109,14 @@ export class NgFor {
}

static bulkInsert(tuples: List<RecordViewTuple>, viewContainer: ViewContainerRef,
protoViewRef: ProtoViewRef): List<RecordViewTuple> {
templateRef: TemplateRef): List<RecordViewTuple> {
tuples.sort((a, b) => a.record.currentIndex - b.record.currentIndex);
for (var i = 0; i < tuples.length; i++) {
var tuple = tuples[i];
if (isPresent(tuple.view)) {
viewContainer.insert(tuple.view, tuple.record.currentIndex);
} else {
tuple.view = viewContainer.create(protoViewRef, tuple.record.currentIndex);
tuple.view = viewContainer.createEmbeddedView(templateRef, tuple.record.currentIndex);
}
}
return tuples;
Expand Down
Loading