diff --git a/modules/angular2/src/core/compiler/element_injector.ts b/modules/angular2/src/core/compiler/element_injector.ts index 3c6a90220c..821d5e736a 100644 --- a/modules/angular2/src/core/compiler/element_injector.ts +++ b/modules/angular2/src/core/compiler/element_injector.ts @@ -771,9 +771,7 @@ export class ElementInjector extends TreeNode { getComponent(): any { return this._strategy.getComponent(); } - getElementRef(): ElementRef { - return new ElementRef(new ViewRef(this._preBuiltObjects.view), this._proto.index); - } + getElementRef(): ElementRef { return this._preBuiltObjects.view.elementRefs[this._proto.index]; } getViewContainerRef(): ViewContainerRef { return new ViewContainerRef(this._preBuiltObjects.viewManager, this.getElementRef()); diff --git a/modules/angular2/src/core/compiler/element_ref.ts b/modules/angular2/src/core/compiler/element_ref.ts index 83e60c969a..583176bb28 100644 --- a/modules/angular2/src/core/compiler/element_ref.ts +++ b/modules/angular2/src/core/compiler/element_ref.ts @@ -1,14 +1,20 @@ import {DOM} from 'angular2/src/dom/dom_adapter'; -import {normalizeBlank} from 'angular2/src/facade/lang'; +import {normalizeBlank, BaseException} from 'angular2/src/facade/lang'; import {ViewRef} from './view_ref'; import {resolveInternalDomView} from 'angular2/src/render/dom/view/view'; +import {RenderViewRef, RenderElementRef} from 'angular2/src/render/api'; /** * @exportedAs angular2/view */ -export class ElementRef { +export class ElementRef implements RenderElementRef { constructor(public parentView: ViewRef, public boundElementIndex: number) {} + get renderView() { return this.parentView.render; } + // TODO(tbosch): remove this once Typescript supports declaring interfaces + // that contain getters + set renderView(value: any) { throw new BaseException('Abstract setter'); } + /** * Exposes the underlying DOM element. * (DEPRECATED way of accessing the DOM, replacement coming) diff --git a/modules/angular2/src/core/compiler/view.ts b/modules/angular2/src/core/compiler/view.ts index b6579a293e..b91b92d137 100644 --- a/modules/angular2/src/core/compiler/view.ts +++ b/modules/angular2/src/core/compiler/view.ts @@ -21,6 +21,8 @@ import {ElementBinder} from './element_binder'; import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang'; import * as renderApi from 'angular2/src/render/api'; import {EventDispatcher} from 'angular2/src/render/api'; +import {ViewRef} from './view_ref'; +import {ElementRef} from './element_ref'; export class AppViewContainer { // The order in this list matches the DOM order. @@ -40,6 +42,8 @@ export class AppView implements ChangeDispatcher, EventDispatcher { componentChildViews: List = null; viewContainers: List; preBuiltObjects: List = null; + elementRefs: List; + ref: ViewRef; /** * The context against which data-binding expressions in this view are evaluated against. @@ -58,6 +62,11 @@ export class AppView implements ChangeDispatcher, EventDispatcher { constructor(public renderer: renderApi.Renderer, public proto: AppProtoView, protoLocals: Map) { this.viewContainers = ListWrapper.createFixedSize(this.proto.elementBinders.length); + this.elementRefs = ListWrapper.createFixedSize(this.proto.elementBinders.length); + this.ref = new ViewRef(this); + for (var i = 0; i < this.elementRefs.length; i++) { + this.elementRefs[i] = new ElementRef(this.ref, i); + } this.locals = new Locals(null, MapWrapper.clone(protoLocals)); // TODO optimize this } @@ -100,14 +109,16 @@ export class AppView implements ChangeDispatcher, EventDispatcher { // dispatch to element injector or text nodes based on context notifyOnBinding(b: BindingRecord, currentValue: any): void { if (b.isElementProperty()) { - this.renderer.setElementProperty(this.render, b.elementIndex, b.propertyName, currentValue); + this.renderer.setElementProperty(this.elementRefs[b.elementIndex], b.propertyName, + currentValue); } else if (b.isElementAttribute()) { - this.renderer.setElementAttribute(this.render, b.elementIndex, b.propertyName, currentValue); + this.renderer.setElementAttribute(this.elementRefs[b.elementIndex], b.propertyName, + currentValue); } else if (b.isElementClass()) { - this.renderer.setElementClass(this.render, b.elementIndex, b.propertyName, currentValue); + this.renderer.setElementClass(this.elementRefs[b.elementIndex], b.propertyName, currentValue); } else if (b.isElementStyle()) { var unit = isPresent(b.propertyUnit) ? b.propertyUnit : ''; - this.renderer.setElementStyle(this.render, b.elementIndex, b.propertyName, + this.renderer.setElementStyle(this.elementRefs[b.elementIndex], b.propertyName, `${currentValue}${unit}`); } else if (b.isTextNode()) { this.renderer.setText(this.render, b.elementIndex, currentValue); @@ -134,7 +145,7 @@ export class AppView implements ChangeDispatcher, EventDispatcher { } invokeElementMethod(elementIndex: number, methodName: string, args: List) { - this.renderer.invokeElementMethod(this.render, elementIndex, methodName, args); + this.renderer.invokeElementMethod(this.elementRefs[elementIndex], methodName, args); } // implementation of EventDispatcher#dispatchEvent diff --git a/modules/angular2/src/core/compiler/view_container_ref.ts b/modules/angular2/src/core/compiler/view_container_ref.ts index 36e723fb7d..f3c56f486e 100644 --- a/modules/angular2/src/core/compiler/view_container_ref.ts +++ b/modules/angular2/src/core/compiler/view_container_ref.ts @@ -24,7 +24,7 @@ export class ViewContainerRef { } } - get(index: number): ViewRef { return new ViewRef(this._getViews()[index]); } + get(index: number): ViewRef { return this._getViews()[index].ref; } get length(): number { return this._getViews().length; } diff --git a/modules/angular2/src/core/compiler/view_manager.ts b/modules/angular2/src/core/compiler/view_manager.ts index 31b04e5112..807cf880c9 100644 --- a/modules/angular2/src/core/compiler/view_manager.ts +++ b/modules/angular2/src/core/compiler/view_manager.ts @@ -22,7 +22,7 @@ export class AppViewManager { getComponentView(hostLocation: ElementRef): ViewRef { var hostView = internalView(hostLocation.parentView); var boundElementIndex = hostLocation.boundElementIndex; - return new ViewRef(hostView.componentChildViews[boundElementIndex]); + return hostView.componentChildViews[boundElementIndex].ref; } getViewContainer(location: ElementRef): ViewContainerRef { @@ -45,7 +45,7 @@ export class AppViewManager { if (isBlank(elementIndex)) { throw new BaseException(`Could not find variable ${variableName}`); } - return new ElementRef(new ViewRef(componentView), elementIndex); + return componentView.elementRefs[elementIndex]; } getComponent(hostLocation: ElementRef): any { @@ -69,7 +69,7 @@ export class AppViewManager { this._utils.hydrateRootHostView(hostView, injector); this._viewHydrateRecurse(hostView); - return new ViewRef(hostView); + return hostView.ref; } destroyRootHostView(hostViewRef: ViewRef) { @@ -98,14 +98,13 @@ export class AppViewManager { var view = this._createPooledView(protoView); - this._renderer.attachViewInContainer(parentView.render, boundElementIndex, atIndex, - view.render); + this._renderer.attachViewInContainer(viewContainerLocation, atIndex, view.render); this._utils.attachViewInContainer(parentView, boundElementIndex, contextView, contextBoundElementIndex, atIndex, view); this._utils.hydrateViewInContainer(parentView, boundElementIndex, contextView, contextBoundElementIndex, atIndex, injector); this._viewHydrateRecurse(view); - return new ViewRef(view); + return view.ref; } destroyViewInContainer(viewContainerLocation: ElementRef, atIndex: number) { @@ -126,8 +125,7 @@ export class AppViewManager { // Right now we are destroying any special // context view that might have been used. this._utils.attachViewInContainer(parentView, boundElementIndex, null, null, atIndex, view); - this._renderer.attachViewInContainer(parentView.render, boundElementIndex, atIndex, - view.render); + this._renderer.attachViewInContainer(viewContainerLocation, atIndex, view.render); return viewRef; } @@ -137,9 +135,8 @@ export class AppViewManager { var viewContainer = parentView.viewContainers[boundElementIndex]; var view = viewContainer.views[atIndex]; this._utils.detachViewInContainer(parentView, boundElementIndex, atIndex); - this._renderer.detachViewInContainer(parentView.render, boundElementIndex, atIndex, - view.render); - return new ViewRef(view); + this._renderer.detachViewInContainer(viewContainerLocation, atIndex, view.render); + return view.ref; } _createPooledView(protoView: viewModule.AppProtoView): viewModule.AppView { @@ -160,7 +157,7 @@ export class AppViewManager { var binder = binders[binderIdx]; if (binder.hasStaticComponent()) { var childView = this._createPooledView(binder.nestedProtoView); - this._renderer.attachComponentView(view.render, binderIdx, childView.render); + this._renderer.attachComponentView(view.elementRefs[binderIdx], childView.render); this._utils.attachComponentView(view, binderIdx, childView); } } @@ -179,14 +176,15 @@ export class AppViewManager { var view = viewContainer.views[atIndex]; this._viewDehydrateRecurse(view, false); this._utils.detachViewInContainer(parentView, boundElementIndex, atIndex); - this._renderer.detachViewInContainer(parentView.render, boundElementIndex, atIndex, + this._renderer.detachViewInContainer(parentView.elementRefs[boundElementIndex], atIndex, view.render); this._destroyPooledView(view); } _destroyComponentView(hostView, boundElementIndex, componentView) { this._viewDehydrateRecurse(componentView, false); - this._renderer.detachComponentView(hostView.render, boundElementIndex, componentView.render); + this._renderer.detachComponentView(hostView.elementRefs[boundElementIndex], + componentView.render); this._utils.detachComponentView(hostView, boundElementIndex); this._destroyPooledView(componentView); } diff --git a/modules/angular2/src/forms/directives/shared.ts b/modules/angular2/src/forms/directives/shared.ts index a65d752117..eda1bbfa2a 100644 --- a/modules/angular2/src/forms/directives/shared.ts +++ b/modules/angular2/src/forms/directives/shared.ts @@ -49,6 +49,5 @@ function _throwError(dir: NgControl, message: string): void { export function setProperty(renderer: Renderer, elementRef: ElementRef, propName: string, propValue: any) { - renderer.setElementProperty(elementRef.parentView.render, elementRef.boundElementIndex, propName, - propValue); -} \ No newline at end of file + renderer.setElementProperty(elementRef, propName, propValue); +} diff --git a/modules/angular2/src/render/api.ts b/modules/angular2/src/render/api.ts index 7048777d89..fced72ed60 100644 --- a/modules/angular2/src/render/api.ts +++ b/modules/angular2/src/render/api.ts @@ -306,6 +306,11 @@ export class RenderCompiler { compile(template: ViewDefinition): Promise { return null; } } +export interface RenderElementRef { + renderView: RenderViewRef; + boundElementIndex: number; +} + export class Renderer { /** * Creates a root host view that includes the given element. @@ -333,29 +338,25 @@ export class Renderer { /** * Attaches a componentView into the given hostView at the given element */ - attachComponentView(hostViewRef: RenderViewRef, elementIndex: number, - componentViewRef: RenderViewRef) {} + attachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef) {} /** * Detaches a componentView into the given hostView at the given element */ - detachComponentView(hostViewRef: RenderViewRef, boundElementIndex: number, - componentViewRef: RenderViewRef) {} + detachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef) {} /** * Attaches a view into a ViewContainer (in the given parentView at the given element) at the * given index. */ - attachViewInContainer(parentViewRef: RenderViewRef, boundElementIndex: number, atIndex: number, - viewRef: RenderViewRef) {} + attachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef) {} /** * Detaches a view into a ViewContainer (in the given parentView at the given element) at the * given index. */ // TODO(tbosch): this should return a promise as it can be animated! - detachViewInContainer(parentViewRef: RenderViewRef, boundElementIndex: number, atIndex: number, - viewRef: RenderViewRef) {} + detachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef) {} /** * Hydrates a view after it has been attached. Hydration/dehydration is used for reusing views @@ -372,32 +373,27 @@ export class Renderer { /** * Sets a property on an element. */ - setElementProperty(viewRef: RenderViewRef, elementIndex: number, propertyName: string, - propertyValue: any) {} + setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any) {} /** * Sets an attribute on an element. */ - setElementAttribute(viewRef: RenderViewRef, elementIndex: number, attributeName: string, - attributeValue: string) {} + setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string) {} /** * Sets a class on an element. */ - setElementClass(viewRef: RenderViewRef, elementIndex: number, className: string, isAdd: boolean) { - } + setElementClass(location: RenderElementRef, className: string, isAdd: boolean) {} /** * Sets a style on an element. */ - setElementStyle(viewRef: RenderViewRef, elementIndex: number, styleName: string, - styleValue: string) {} + setElementStyle(location: RenderElementRef, styleName: string, styleValue: string) {} /** * Calls a method on an element. */ - invokeElementMethod(viewRef: RenderViewRef, elementIndex: number, methodName: string, - args: List) {} + invokeElementMethod(location: RenderElementRef, methodName: string, args: List) {} /** * Sets the value of a text node. diff --git a/modules/angular2/src/render/dom/dom_renderer.ts b/modules/angular2/src/render/dom/dom_renderer.ts index 67a8582ca7..ec41cd455e 100644 --- a/modules/angular2/src/render/dom/dom_renderer.ts +++ b/modules/angular2/src/render/dom/dom_renderer.ts @@ -20,7 +20,7 @@ import {DomElement} from './view/element'; import {DomViewContainer} from './view/view_container'; import {NG_BINDING_CLASS_SELECTOR, NG_BINDING_CLASS} from './util'; -import {Renderer, RenderProtoViewRef, RenderViewRef} from '../api'; +import {Renderer, RenderProtoViewRef, RenderViewRef, RenderElementRef} from '../api'; export const DOCUMENT_TOKEN = CONST_EXPR(new OpaqueToken('DocumentToken')); @@ -53,12 +53,11 @@ export class DomRenderer extends Renderer { // noop for now } - attachComponentView(hostViewRef: RenderViewRef, elementIndex: number, - componentViewRef: RenderViewRef) { - var hostView = resolveInternalDomView(hostViewRef); + attachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef) { + var hostView = resolveInternalDomView(location.renderView); var componentView = resolveInternalDomView(componentViewRef); - var element = hostView.boundElements[elementIndex].element; - var lightDom = hostView.boundElements[elementIndex].lightDom; + var element = hostView.boundElements[location.boundElementIndex].element; + var lightDom = hostView.boundElements[location.boundElementIndex].lightDom; if (isPresent(lightDom)) { lightDom.attachShadowDomView(componentView); } @@ -79,12 +78,11 @@ export class DomRenderer extends Renderer { return resolveInternalDomView(viewRef).rootNodes; } - detachComponentView(hostViewRef: RenderViewRef, boundElementIndex: number, - componentViewRef: RenderViewRef) { - var hostView = resolveInternalDomView(hostViewRef); + detachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef) { + var hostView = resolveInternalDomView(location.renderView); var componentView = resolveInternalDomView(componentViewRef); this._removeViewNodes(componentView); - var lightDom = hostView.boundElements[boundElementIndex].lightDom; + var lightDom = hostView.boundElements[location.boundElementIndex].lightDom; if (isPresent(lightDom)) { lightDom.detachShadowDomView(); } @@ -92,19 +90,18 @@ export class DomRenderer extends Renderer { componentView.shadowRoot = null; } - attachViewInContainer(parentViewRef: RenderViewRef, boundElementIndex: number, atIndex: number, - viewRef: RenderViewRef) { - var parentView = resolveInternalDomView(parentViewRef); + attachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef) { + var parentView = resolveInternalDomView(location.renderView); var view = resolveInternalDomView(viewRef); - var viewContainer = this._getOrCreateViewContainer(parentView, boundElementIndex); + var viewContainer = this._getOrCreateViewContainer(parentView, location.boundElementIndex); ListWrapper.insert(viewContainer.views, atIndex, view); view.hostLightDom = parentView.hostLightDom; - var directParentLightDom = this._directParentLightDom(parentView, boundElementIndex); + var directParentLightDom = this._directParentLightDom(parentView, location.boundElementIndex); if (isBlank(directParentLightDom)) { var siblingToInsertAfter; if (atIndex == 0) { - siblingToInsertAfter = parentView.boundElements[boundElementIndex].element; + siblingToInsertAfter = parentView.boundElements[location.boundElementIndex].element; } else { siblingToInsertAfter = ListWrapper.last(viewContainer.views[atIndex - 1].rootNodes); } @@ -118,14 +115,13 @@ export class DomRenderer extends Renderer { } } - detachViewInContainer(parentViewRef: RenderViewRef, boundElementIndex: number, atIndex: number, - viewRef: RenderViewRef) { - var parentView = resolveInternalDomView(parentViewRef); + detachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef) { + var parentView = resolveInternalDomView(location.renderView); var view = resolveInternalDomView(viewRef); - var viewContainer = parentView.boundElements[boundElementIndex].viewContainer; + var viewContainer = parentView.boundElements[location.boundElementIndex].viewContainer; var detachedView = viewContainer.views[atIndex]; ListWrapper.removeAt(viewContainer.views, atIndex); - var directParentLightDom = this._directParentLightDom(parentView, boundElementIndex); + var directParentLightDom = this._directParentLightDom(parentView, location.boundElementIndex); if (isBlank(directParentLightDom)) { this._removeViewNodes(detachedView); } else { @@ -181,34 +177,30 @@ export class DomRenderer extends Renderer { view.hydrated = false; } - setElementProperty(viewRef: RenderViewRef, elementIndex: number, propertyName: string, - propertyValue: any): void { - var view = resolveInternalDomView(viewRef); - view.setElementProperty(elementIndex, propertyName, propertyValue); + setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any): void { + var view = resolveInternalDomView(location.renderView); + view.setElementProperty(location.boundElementIndex, propertyName, propertyValue); } - setElementAttribute(viewRef: RenderViewRef, elementIndex: number, attributeName: string, + setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string): void { - var view = resolveInternalDomView(viewRef); - view.setElementAttribute(elementIndex, attributeName, attributeValue); + var view = resolveInternalDomView(location.renderView); + view.setElementAttribute(location.boundElementIndex, attributeName, attributeValue); } - setElementClass(viewRef: RenderViewRef, elementIndex: number, className: string, - isAdd: boolean): void { - var view = resolveInternalDomView(viewRef); - view.setElementClass(elementIndex, className, isAdd); + setElementClass(location: RenderElementRef, className: string, isAdd: boolean): void { + var view = resolveInternalDomView(location.renderView); + view.setElementClass(location.boundElementIndex, className, isAdd); } - setElementStyle(viewRef: RenderViewRef, elementIndex: number, styleName: string, - styleValue: string): void { - var view = resolveInternalDomView(viewRef); - view.setElementStyle(elementIndex, styleName, styleValue); + setElementStyle(location: RenderElementRef, styleName: string, styleValue: string): void { + var view = resolveInternalDomView(location.renderView); + view.setElementStyle(location.boundElementIndex, styleName, styleValue); } - invokeElementMethod(viewRef: RenderViewRef, elementIndex: number, methodName: string, - args: List): void { - var view = resolveInternalDomView(viewRef); - view.invokeElementMethod(elementIndex, methodName, args); + invokeElementMethod(location: RenderElementRef, methodName: string, args: List): void { + var view = resolveInternalDomView(location.renderView); + view.invokeElementMethod(location.boundElementIndex, methodName, args); } setText(viewRef: RenderViewRef, textNodeIndex: number, text: string): void { diff --git a/modules/angular2/test/core/compiler/element_injector_spec.ts b/modules/angular2/test/core/compiler/element_injector_spec.ts index 760b24ca7b..6e723ddebd 100644 --- a/modules/angular2/test/core/compiler/element_injector_spec.ts +++ b/modules/angular2/test/core/compiler/element_injector_spec.ts @@ -51,7 +51,6 @@ import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref'; import {ElementRef} from 'angular2/src/core/compiler/element_ref'; import {DynamicChangeDetector, ChangeDetectorRef, Parser, Lexer} from 'angular2/change_detection'; -import {Renderer} from 'angular2/src/render/api'; import {QueryList} from 'angular2/src/core/compiler/query_list'; @proxy @@ -59,14 +58,25 @@ import {QueryList} from 'angular2/src/core/compiler/query_list'; class DummyView extends SpyObject { componentChildViews; changeDetector; - constructor() { - super(); + elementRefs; + constructor(elementCount = 0) { + super(AppView); this.componentChildViews = []; this.changeDetector = null; + this.elementRefs = ListWrapper.createFixedSize(elementCount); + for (var i=0; i { } export function main() { - var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null); + var defaultPreBuiltObjects = new PreBuiltObjects(null, new DummyView(1), null); var appInjector = Injector.resolveAndCreate([]); // An injector with more than 10 bindings will switch to the dynamic strategy @@ -893,7 +903,7 @@ export function main() { describe("refs", () => { it("should inject ElementRef", () => { var inj = injector(ListWrapper.concat([NeedsElementRef], extraBindings)); - expect(inj.get(NeedsElementRef).elementRef).toBeAnInstanceOf(ElementRef); + expect(inj.get(NeedsElementRef).elementRef).toBe(defaultPreBuiltObjects.view.elementRefs[0]); }); it('should inject ChangeDetectorRef', () => { @@ -1005,7 +1015,7 @@ export function main() { var inj = injector(ListWrapper.concat(dirs, extraBindings), null, false, preBuildObjects, null, dirVariableBindings); - expect(inj.get(NeedsQueryByVarBindings).query.first).toBeAnInstanceOf(ElementRef); + expect(inj.get(NeedsQueryByVarBindings).query.first).toBe(defaultPreBuiltObjects.view.elementRefs[0]); }); it('should contain directives on the same injector when querying by variable bindings' + @@ -1139,14 +1149,3 @@ class ContextWithHandler { handler; constructor(handler) { this.handler = handler; } } - -class FakeRenderer extends Renderer { - log: List>; - constructor() { - super(); - this.log = []; - } - setElementProperty(viewRef, elementIndex, propertyName, value) { - this.log.push([viewRef, elementIndex, propertyName, value]); - } -} diff --git a/modules/angular2/test/core/compiler/view_manager_spec.ts b/modules/angular2/test/core/compiler/view_manager_spec.ts index 867628b608..211d2ee5a5 100644 --- a/modules/angular2/test/core/compiler/view_manager_spec.ts +++ b/modules/angular2/test/core/compiler/view_manager_spec.ts @@ -292,13 +292,13 @@ export function main() { it('should attach the view', () => { var contextView = createView(); - manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, - wrapPv(childProtoView), + var elRef = elementRef(wrapView(parentView), 0); + manager.createViewInContainer(elRef, 0, wrapPv(childProtoView), elementRef(wrapView(contextView), 1), null); expect(utils.spy('attachViewInContainer')) .toHaveBeenCalledWith(parentView, 0, contextView, 1, 0, createdViews[0]); expect(renderer.spy('attachViewInContainer')) - .toHaveBeenCalledWith(parentView.render, 0, 0, createdViews[0].render); + .toHaveBeenCalledWith(elRef, 0, createdViews[0].render); }); it('should hydrate the view', () => { @@ -349,10 +349,11 @@ export function main() { }); it('should detach', () => { - manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0); + var elRef = elementRef(wrapView(parentView), 0); + manager.destroyViewInContainer(elRef, 0); expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0); expect(renderer.spy('detachViewInContainer')) - .toHaveBeenCalledWith(parentView.render, 0, 0, childView.render); + .toHaveBeenCalledWith(elRef, 0, childView.render); }); it('should return the view to the pool', () => { @@ -381,7 +382,7 @@ export function main() { manager.destroyRootHostView(wrapView(parentView)); expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0); expect(renderer.spy('detachViewInContainer')) - .toHaveBeenCalledWith(parentView.render, 0, 0, childView.render); + .toHaveBeenCalledWith(parentView.elementRefs[0], 0, childView.render); }); it('should return the view to the pool', () => { diff --git a/modules/angular2/test/render/dom/dom_renderer_integration_spec.ts b/modules/angular2/test/render/dom/dom_renderer_integration_spec.ts index 47cee1a733..a44022f501 100644 --- a/modules/angular2/test/render/dom/dom_renderer_integration_spec.ts +++ b/modules/angular2/test/render/dom/dom_renderer_integration_spec.ts @@ -16,7 +16,7 @@ import { import {MapWrapper} from 'angular2/src/facade/collection'; import {DOM} from 'angular2/src/dom/dom_adapter'; -import {DomTestbed, TestView} from './dom_testbed'; +import {DomTestbed, TestView, elRef} from './dom_testbed'; import {ViewDefinition, DirectiveMetadata, RenderViewRef} from 'angular2/src/render/api'; @@ -106,20 +106,20 @@ export function main() { var cmpView = tb.createComponentView(rootView.viewRef, 0, protoViewDtos[1]); var el = DOM.childNodes(tb.rootEl)[0]; - tb.renderer.setElementProperty(cmpView.viewRef, 0, 'value', 'hello'); + tb.renderer.setElementProperty(elRef(cmpView.viewRef, 0), 'value', 'hello'); expect(el.value).toEqual('hello'); - tb.renderer.setElementClass(cmpView.viewRef, 0, 'a', true); + tb.renderer.setElementClass(elRef(cmpView.viewRef, 0), 'a', true); expect(DOM.childNodes(tb.rootEl)[0].value).toEqual('hello'); - tb.renderer.setElementClass(cmpView.viewRef, 0, 'a', false); + tb.renderer.setElementClass(elRef(cmpView.viewRef, 0), 'a', false); expect(DOM.hasClass(el, 'a')).toBe(false); - tb.renderer.setElementStyle(cmpView.viewRef, 0, 'width', '10px'); + tb.renderer.setElementStyle(elRef(cmpView.viewRef, 0), 'width', '10px'); expect(DOM.getStyle(el, 'width')).toEqual('10px'); - tb.renderer.setElementStyle(cmpView.viewRef, 0, 'width', null); + tb.renderer.setElementStyle(elRef(cmpView.viewRef, 0), 'width', null); expect(DOM.getStyle(el, 'width')).toEqual(''); - tb.renderer.setElementAttribute(cmpView.viewRef, 0, 'someAttr', 'someValue'); + tb.renderer.setElementAttribute(elRef(cmpView.viewRef, 0), 'someAttr', 'someValue'); expect(DOM.getAttribute(el, 'some-attr')).toEqual('someValue'); async.done(); @@ -141,7 +141,7 @@ export function main() { var views = tb.createRootViews(protoViewDtos); var componentView = views[1]; - tb.renderer.invokeElementMethod(componentView.viewRef, 0, 'setAttribute', + tb.renderer.invokeElementMethod(elRef(componentView.viewRef, 0), 'setAttribute', ['a', 'b']); expect(DOM.getAttribute(DOM.childNodes(tb.rootEl)[0], 'a')).toEqual('b'); diff --git a/modules/angular2/test/render/dom/dom_testbed.ts b/modules/angular2/test/render/dom/dom_testbed.ts index 642e3010eb..e5ba5c1a9a 100644 --- a/modules/angular2/test/render/dom/dom_testbed.ts +++ b/modules/angular2/test/render/dom/dom_testbed.ts @@ -11,7 +11,8 @@ import { ProtoViewDto, ViewDefinition, EventDispatcher, - DirectiveMetadata + DirectiveMetadata, + RenderElementRef } from 'angular2/src/render/api'; import {resolveInternalDomView} from 'angular2/src/render/dom/view/view'; import {el, dispatchEvent} from 'angular2/test_lib'; @@ -28,6 +29,13 @@ export class TestView { } } +export function elRef(renderView: RenderViewRef, boundElementIndex: number) { + return new TestRenderElementRef(renderView, boundElementIndex); +} + +class TestRenderElementRef implements RenderElementRef { + constructor(public renderView: RenderViewRef, public boundElementIndex: number) {} +} class LoggingEventDispatcher implements EventDispatcher { log: List>; @@ -85,7 +93,7 @@ export class DomTestbed { createComponentView(parentViewRef: RenderViewRef, boundElementIndex: number, componentProtoView: ProtoViewDto): TestView { var componentViewRef = this.renderer.createView(componentProtoView.render); - this.renderer.attachComponentView(parentViewRef, boundElementIndex, componentViewRef); + this.renderer.attachComponentView(elRef(parentViewRef, boundElementIndex), componentViewRef); this.renderer.hydrateView(componentViewRef); return this._createTestView(componentViewRef); } @@ -104,13 +112,13 @@ export class DomTestbed { destroyComponentView(parentViewRef: RenderViewRef, boundElementIndex: number, componentView: RenderViewRef) { this.renderer.dehydrateView(componentView); - this.renderer.detachComponentView(parentViewRef, boundElementIndex, componentView); + this.renderer.detachComponentView(elRef(parentViewRef, boundElementIndex), componentView); } createViewInContainer(parentViewRef: RenderViewRef, boundElementIndex: number, atIndex: number, protoView: ProtoViewDto): TestView { var viewRef = this.renderer.createView(protoView.render); - this.renderer.attachViewInContainer(parentViewRef, boundElementIndex, atIndex, viewRef); + this.renderer.attachViewInContainer(elRef(parentViewRef, boundElementIndex), atIndex, viewRef); this.renderer.hydrateView(viewRef); return this._createTestView(viewRef); } @@ -118,7 +126,7 @@ export class DomTestbed { destroyViewInContainer(parentViewRef: RenderViewRef, boundElementIndex: number, atIndex: number, viewRef: RenderViewRef) { this.renderer.dehydrateView(viewRef); - this.renderer.detachViewInContainer(parentViewRef, boundElementIndex, atIndex, viewRef); + this.renderer.detachViewInContainer(elRef(parentViewRef, boundElementIndex), atIndex, viewRef); this.renderer.destroyView(viewRef); } diff --git a/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.ts b/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.ts index 6b79f245b9..36ea9dacaa 100644 --- a/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.ts +++ b/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.ts @@ -32,7 +32,7 @@ import { import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver'; import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner'; -import {DomTestbed} from './dom_testbed'; +import {DomTestbed, elRef} from './dom_testbed'; export function main() { describe('ShadowDom integration tests', function() { @@ -425,17 +425,21 @@ export function main() { expect(tb.rootEl).toHaveText('(TAB(0))'); tb.renderer.dehydrateView(tabChildView.viewRef); - tb.renderer.detachViewInContainer(tab1View.viewRef, 0, 0, tabChildView.viewRef); + tb.renderer.detachViewInContainer(elRef(tab1View.viewRef, 0), 0, + tabChildView.viewRef); - tb.renderer.attachViewInContainer(tab2View.viewRef, 0, 0, tabChildView.viewRef); + tb.renderer.attachViewInContainer(elRef(tab2View.viewRef, 0), 0, + tabChildView.viewRef); tb.renderer.hydrateView(tabChildView.viewRef); expect(tb.rootEl).toHaveText('(TAB(1))'); tb.renderer.dehydrateView(tabChildView.viewRef); - tb.renderer.detachViewInContainer(tab2View.viewRef, 0, 0, tabChildView.viewRef); + tb.renderer.detachViewInContainer(elRef(tab2View.viewRef, 0), 0, + tabChildView.viewRef); - tb.renderer.attachViewInContainer(tab3View.viewRef, 0, 0, tabChildView.viewRef); + tb.renderer.attachViewInContainer(elRef(tab3View.viewRef, 0), 0, + tabChildView.viewRef); tb.renderer.hydrateView(tabChildView.viewRef); expect(tb.rootEl).toHaveText('(TAB(2))');