feat(core): add attachView / detachView to ApplicationRef

This feature is useful to allow components / embedded views
to be dirty checked if they are not placed in any `ViewContainer`.

Closes #9293
This commit is contained in:
Tobias Bosch
2016-11-04 11:58:06 -07:00
committed by Victor Berchet
parent 9de76ebfa5
commit 9f7d32a326
4 changed files with 149 additions and 29 deletions

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ApplicationRef} from '../application_ref';
import {ChangeDetectorRef, ChangeDetectorStatus} from '../change_detection/change_detection';
import {Injector, THROW_IF_NOT_FOUND} from '../di/injector';
import {ListWrapper} from '../facade/collection';
@ -41,7 +42,10 @@ export abstract class AppView<T> {
lastRootNode: any;
allNodes: any[];
disposables: Function[];
viewContainer: ViewContainer = null;
viewContainer: ViewContainer;
// This will be set if a view is directly attached to an ApplicationRef
// and not to a view container.
appRef: ApplicationRef;
numberOfChecks: number = 0;
@ -138,10 +142,12 @@ export abstract class AppView<T> {
injector(nodeIndex: number): Injector { return new ElementInjector(this, nodeIndex); }
detachAndDestroy() {
if (this._hasExternalHostElement) {
this.detach();
} else if (isPresent(this.viewContainer)) {
if (this.viewContainer) {
this.viewContainer.detachView(this.viewContainer.nestedViews.indexOf(this));
} else if (this.appRef) {
this.appRef.detachView(this.ref);
} else if (this._hasExternalHostElement) {
this.detach();
}
this.destroy();
}
@ -196,6 +202,7 @@ export abstract class AppView<T> {
projectedViews.splice(index, 1);
}
}
this.appRef = null;
this.viewContainer = null;
this.dirtyParentQueriesInternal();
}
@ -208,7 +215,18 @@ export abstract class AppView<T> {
}
}
attachToAppRef(appRef: ApplicationRef) {
if (this.viewContainer) {
throw new Error('This view is already attached to a ViewContainer!');
}
this.appRef = appRef;
this.dirtyParentQueriesInternal();
}
attachAfter(viewContainer: ViewContainer, prevView: AppView<any>) {
if (this.appRef) {
throw new Error('This view is already attached directly to the ApplicationRef!');
}
this._renderAttach(viewContainer, prevView);
this.viewContainer = viewContainer;
if (this.declaredViewContainer && this.declaredViewContainer !== viewContainer) {