feat(view): allow to transplant a view into a ViewContainer at another place.
Closes #1492.
This commit is contained in:
@ -88,7 +88,7 @@ export class DynamicComponentLoader {
|
||||
var binding = this._getBinding(typeOrBinding);
|
||||
return this._compiler.compileInHost(binding).then(hostProtoViewRef => {
|
||||
var viewContainer = this._viewManager.getViewContainer(location);
|
||||
var hostViewRef = viewContainer.create(hostProtoViewRef, viewContainer.length, injector);
|
||||
var hostViewRef = viewContainer.create(hostProtoViewRef, viewContainer.length, null, injector);
|
||||
var newLocation = new ElementRef(hostViewRef, 0);
|
||||
var component = this._viewManager.getComponent(newLocation);
|
||||
|
||||
|
@ -40,9 +40,9 @@ 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, injector:Injector = null): ViewRef {
|
||||
create(protoViewRef:ProtoViewRef = null, atIndex:number=-1, context:ElementRef, injector:Injector = null): ViewRef {
|
||||
if (atIndex == -1) atIndex = this.length;
|
||||
return this._viewManager.createViewInContainer(this._element, atIndex, protoViewRef, injector);
|
||||
return this._viewManager.createViewInContainer(this._element, atIndex, protoViewRef, context, injector);
|
||||
}
|
||||
|
||||
insert(viewRef:ViewRef, atIndex:number=-1): ViewRef {
|
||||
@ -68,4 +68,4 @@ export class ViewContainerRef {
|
||||
if (atIndex == -1) atIndex = this.length - 1;
|
||||
return this._viewManager.detachViewInContainer(this._element, atIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,16 +92,22 @@ export class AppViewManager {
|
||||
}
|
||||
|
||||
createViewInContainer(viewContainerLocation:ElementRef,
|
||||
atIndex:number, protoViewRef:ProtoViewRef, injector:Injector = null):ViewRef {
|
||||
atIndex:number, protoViewRef:ProtoViewRef, context:ElementRef = null, injector:Injector = null):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;
|
||||
}
|
||||
|
||||
var view = this._createPooledView(protoView);
|
||||
|
||||
this._renderer.attachViewInContainer(parentView.render, boundElementIndex, atIndex, view.render);
|
||||
this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view);
|
||||
this._utils.hydrateViewInContainer(parentView, boundElementIndex, atIndex, injector);
|
||||
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);
|
||||
}
|
||||
@ -116,7 +122,13 @@ export class AppViewManager {
|
||||
var view = internalView(viewRef);
|
||||
var parentView = internalView(viewContainerLocation.parentView);
|
||||
var boundElementIndex = viewContainerLocation.boundElementIndex;
|
||||
this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view);
|
||||
// TODO(tbosch): the public methods attachViewInContainer/detachViewInContainer
|
||||
// are used for moving elements without the same container.
|
||||
// We will change this into an atomic `move` operation, which should preserve the
|
||||
// previous parent injector (see https://github.com/angular/angular/issues/1377).
|
||||
// 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);
|
||||
return viewRef;
|
||||
}
|
||||
|
@ -114,7 +114,12 @@ export class AppViewManagerUtils {
|
||||
}
|
||||
|
||||
attachViewInContainer(parentView:viewModule.AppView, boundElementIndex:number,
|
||||
contextView:viewModule.AppView, contextBoundElementIndex:number,
|
||||
atIndex:number, view:viewModule.AppView) {
|
||||
if (isBlank(contextView)) {
|
||||
contextView = parentView;
|
||||
contextBoundElementIndex = boundElementIndex;
|
||||
}
|
||||
parentView.changeDetector.addChild(view.changeDetector);
|
||||
var viewContainer = parentView.viewContainers[boundElementIndex];
|
||||
if (isBlank(viewContainer)) {
|
||||
@ -128,7 +133,7 @@ export class AppViewManagerUtils {
|
||||
} else {
|
||||
sibling = ListWrapper.last(viewContainer.views[atIndex - 1].rootElementInjectors)
|
||||
}
|
||||
var elementInjector = parentView.elementInjectors[boundElementIndex];
|
||||
var elementInjector = contextView.elementInjectors[contextBoundElementIndex];
|
||||
for (var i = view.rootElementInjectors.length - 1; i >= 0; i--) {
|
||||
view.rootElementInjectors[i].linkAfter(elementInjector, sibling);
|
||||
}
|
||||
@ -145,11 +150,16 @@ export class AppViewManagerUtils {
|
||||
}
|
||||
|
||||
hydrateViewInContainer(parentView:viewModule.AppView, boundElementIndex:number,
|
||||
contextView:viewModule.AppView, contextBoundElementIndex:number,
|
||||
atIndex:number, injector:Injector) {
|
||||
if (isBlank(contextView)) {
|
||||
contextView = parentView;
|
||||
contextBoundElementIndex = boundElementIndex;
|
||||
}
|
||||
var viewContainer = parentView.viewContainers[boundElementIndex];
|
||||
var view = viewContainer.views[atIndex];
|
||||
var elementInjector = parentView.elementInjectors[boundElementIndex];
|
||||
this._hydrateView(view, injector, elementInjector, parentView.context, parentView.locals);
|
||||
var elementInjector = contextView.elementInjectors[contextBoundElementIndex].getHost();
|
||||
this._hydrateView(view, injector, elementInjector, contextView.context, contextView.locals);
|
||||
}
|
||||
|
||||
hydrateDynamicComponentInElementInjector(hostView:viewModule.AppView, boundElementIndex:number,
|
||||
|
2
modules/angular2/src/router/router_outlet.js
vendored
2
modules/angular2/src/router/router_outlet.js
vendored
@ -37,7 +37,7 @@ export class RouterOutlet {
|
||||
]);
|
||||
|
||||
this._viewContainer.clear();
|
||||
this._viewContainer.create(pv, 0, outletInjector);
|
||||
this._viewContainer.create(pv, 0, null, outletInjector);
|
||||
});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user