refactor(portal): rename PortalHost to PortalOutlet (#7546)

Renames the `PortalHost` and related symbols to `PortalOutlet` for consistency with core.

Fixes #7544.
This commit is contained in:
Kristiyan Kostadinov
2017-10-30 22:04:36 +01:00
committed by mmalerba
parent f601e8335f
commit 00de3f6509
20 changed files with 135 additions and 125 deletions
+7 -7
View File
@@ -7,7 +7,7 @@
*/
import {NgZone} from '@angular/core';
import {PortalHost, Portal} from '@angular/cdk/portal';
import {PortalOutlet, Portal} from '@angular/cdk/portal';
import {OverlayConfig} from './overlay-config';
import {OverlayKeyboardDispatcher} from './keyboard/overlay-keyboard-dispatcher';
import {Observable} from 'rxjs/Observable';
@@ -19,7 +19,7 @@ import {first} from 'rxjs/operators';
* Reference to an overlay that has been created with the Overlay service.
* Used to manipulate or dispose of said overlay.
*/
export class OverlayRef implements PortalHost {
export class OverlayRef implements PortalOutlet {
private _backdropElement: HTMLElement | null = null;
private _backdropClick: Subject<any> = new Subject();
private _attachments = new Subject<void>();
@@ -29,7 +29,7 @@ export class OverlayRef implements PortalHost {
_keydownEvents = new Subject<KeyboardEvent>();
constructor(
private _portalHost: PortalHost,
private _portalOutlet: PortalOutlet,
private _pane: HTMLElement,
private _config: OverlayConfig,
private _ngZone: NgZone,
@@ -51,7 +51,7 @@ export class OverlayRef implements PortalHost {
* @returns The portal attachment result.
*/
attach(portal: Portal<any>): any {
let attachResult = this._portalHost.attach(portal);
let attachResult = this._portalOutlet.attach(portal);
if (this._config.positionStrategy) {
this._config.positionStrategy.attach(this);
@@ -118,7 +118,7 @@ export class OverlayRef implements PortalHost {
this._config.scrollStrategy.disable();
}
const detachmentResult = this._portalHost.detach();
const detachmentResult = this._portalOutlet.detach();
// Only emit after everything is detached.
this._detachments.next();
@@ -142,7 +142,7 @@ export class OverlayRef implements PortalHost {
}
this.detachBackdrop();
this._portalHost.dispose();
this._portalOutlet.dispose();
this._attachments.complete();
this._backdropClick.complete();
this._detachments.next();
@@ -153,7 +153,7 @@ export class OverlayRef implements PortalHost {
* Checks whether the overlay has been attached.
*/
hasAttached(): boolean {
return this._portalHost.hasAttached();
return this._portalOutlet.hasAttached();
}
/**
+1 -1
View File
@@ -4,7 +4,7 @@ The `overlay` package provides a way to open floating panels on the screen.
Calling `overlay.create()` will return an `OverlayRef` instance. This instance is a handle for
managing that specific overlay.
The `OverlayRef` _is_ a `PortalHost`- once created, content can be added by attaching a `Portal`.
The `OverlayRef` _is_ a `PortalOutlet`- once created, content can be added by attaching a `Portal`.
See the documentation on portals for further information.
```ts
const overlayRef = overlay.create();
+9 -9
View File
@@ -13,7 +13,7 @@ import {
Injector,
NgZone,
} from '@angular/core';
import {DomPortalHost} from '@angular/cdk/portal';
import {DomPortalOutlet} from '@angular/cdk/portal';
import {OverlayConfig} from './overlay-config';
import {OverlayRef} from './overlay-ref';
import {OverlayPositionBuilder} from './position/overlay-position-builder';
@@ -35,7 +35,7 @@ let defaultConfig = new OverlayConfig();
* selects, etc. can all be built using overlays. The service should primarily be used by authors
* of re-usable components rather than developers building end-user applications.
*
* An overlay *is* a PortalHost, so any kind of Portal can be loaded into one.
* An overlay *is* a PortalOutlet, so any kind of Portal can be loaded into one.
*/
@Injectable()
export class Overlay {
@@ -57,8 +57,8 @@ export class Overlay {
*/
create(config: OverlayConfig = defaultConfig): OverlayRef {
const pane = this._createPaneElement();
const portalHost = this._createPortalHost(pane);
return new OverlayRef(portalHost, pane, config, this._ngZone, this._keyboardDispatcher);
const portalOutlet = this._createPortalOutlet(pane);
return new OverlayRef(portalOutlet, pane, config, this._ngZone, this._keyboardDispatcher);
}
/**
@@ -85,12 +85,12 @@ export class Overlay {
}
/**
* Create a DomPortalHost into which the overlay content can be loaded.
* @param pane The DOM element to turn into a portal host.
* @returns A portal host for the given DOM element.
* Create a DomPortalOutlet into which the overlay content can be loaded.
* @param pane The DOM element to turn into a portal outlet.
* @returns A portal outlet for the given DOM element.
*/
private _createPortalHost(pane: HTMLElement): DomPortalHost {
return new DomPortalHost(pane, this._componentFactoryResolver, this._appRef, this._injector);
private _createPortalOutlet(pane: HTMLElement): DomPortalOutlet {
return new DomPortalOutlet(pane, this._componentFactoryResolver, this._appRef, this._injector);
}
}
@@ -13,14 +13,14 @@ import {
ApplicationRef,
Injector,
} from '@angular/core';
import {BasePortalHost, ComponentPortal, TemplatePortal} from './portal';
import {BasePortalOutlet, ComponentPortal, TemplatePortal} from './portal';
/**
* A PortalHost for attaching portals to an arbitrary DOM element outside of the Angular
* A PortalOutlet for attaching portals to an arbitrary DOM element outside of the Angular
* application context.
*/
export class DomPortalHost extends BasePortalHost {
export class DomPortalOutlet extends BasePortalOutlet {
constructor(
private _hostDomElement: Element,
private _componentFactoryResolver: ComponentFactoryResolver,
@@ -75,8 +75,9 @@ export class DomPortalHost extends BasePortalHost {
viewRef.detectChanges();
// The method `createEmbeddedView` will add the view as a child of the viewContainer.
// But for the DomPortalHost the view can be added everywhere in the DOM (e.g Overlay Container)
// To move the view to the specified host element. We just re-append the existing root nodes.
// But for the DomPortalOutlet the view can be added everywhere in the DOM
// (e.g Overlay Container) To move the view to the specified host element. We just
// re-append the existing root nodes.
viewRef.rootNodes.forEach(rootNode => this._hostDomElement.appendChild(rootNode));
this.setDisposeFn((() => {
+18 -13
View File
@@ -17,7 +17,7 @@ import {
OnDestroy,
Input,
} from '@angular/core';
import {Portal, TemplatePortal, ComponentPortal, BasePortalHost} from './portal';
import {Portal, TemplatePortal, ComponentPortal, BasePortalOutlet} from './portal';
/**
@@ -36,18 +36,18 @@ export class TemplatePortalDirective extends TemplatePortal<any> {
/**
* Directive version of a PortalHost. Because the directive *is* a PortalHost, portals can be
* Directive version of a PortalOutlet. Because the directive *is* a PortalOutlet, portals can be
* directly attached to it, enabling declarative use.
*
* Usage:
* <ng-template [cdkPortalHost]="greeting"></ng-template>
* <ng-template [cdkPortalOutlet]="greeting"></ng-template>
*/
@Directive({
selector: '[cdkPortalHost], [portalHost]',
exportAs: 'cdkPortalHost',
inputs: ['portal: cdkPortalHost']
selector: '[cdkPortalOutlet], [cdkPortalHost], [portalHost]',
exportAs: 'cdkPortalOutlet, cdkPortalHost',
inputs: ['portal: cdkPortalOutlet']
})
export class PortalHostDirective extends BasePortalHost implements OnDestroy {
export class PortalOutletDirective extends BasePortalOutlet implements OnDestroy {
/** The attached portal. */
private _portal: Portal<any> | null = null;
@@ -62,7 +62,12 @@ export class PortalHostDirective extends BasePortalHost implements OnDestroy {
get _deprecatedPortal() { return this.portal; }
set _deprecatedPortal(v) { this.portal = v; }
/** Portal associated with the Portal host. */
/** @deprecated */
@Input('cdkPortalHost')
get _deprecatedPortalHost() { return this.portal; }
set _deprecatedPortalHost(v) { this.portal = v; }
/** Portal associated with the Portal outlet. */
get portal(): Portal<any> | null {
return this._portal;
}
@@ -85,16 +90,16 @@ export class PortalHostDirective extends BasePortalHost implements OnDestroy {
}
/**
* Attach the given ComponentPortal to this PortalHost using the ComponentFactoryResolver.
* Attach the given ComponentPortal to this PortalOutlet using the ComponentFactoryResolver.
*
* @param portal Portal to be attached to the portal host.
* @param portal Portal to be attached to the portal outlet.
* @returns Reference to the created component.
*/
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
portal.setAttachedHost(this);
// If the portal specifies an origin, use that as the logical location of the component
// in the application tree. Otherwise use the location of this PortalHost.
// in the application tree. Otherwise use the location of this PortalOutlet.
let viewContainerRef = portal.viewContainerRef != null ?
portal.viewContainerRef :
this._viewContainerRef;
@@ -129,7 +134,7 @@ export class PortalHostDirective extends BasePortalHost implements OnDestroy {
@NgModule({
exports: [TemplatePortalDirective, PortalHostDirective],
declarations: [TemplatePortalDirective, PortalHostDirective],
exports: [TemplatePortalDirective, PortalOutletDirective],
declarations: [TemplatePortalDirective, PortalOutletDirective],
})
export class PortalModule {}
+6 -6
View File
@@ -26,8 +26,8 @@ export function throwPortalAlreadyAttachedError() {
* Throws an exception when attempting to attach a portal to an already-disposed host.
* @docs-private
*/
export function throwPortalHostAlreadyDisposedError() {
throw Error('This PortalHost has already been disposed');
export function throwPortalOutletAlreadyDisposedError() {
throw Error('This PortalOutlet has already been disposed');
}
/**
@@ -35,16 +35,16 @@ export function throwPortalHostAlreadyDisposedError() {
* @docs-private
*/
export function throwUnknownPortalTypeError() {
throw Error('Attempting to attach an unknown Portal type. BasePortalHost accepts either ' +
'a ComponentPortal or a TemplatePortal.');
throw Error('Attempting to attach an unknown Portal type. BasePortalOutlet accepts either ' +
'a ComponentPortal or a TemplatePortal.');
}
/**
* Throws an exception when attempting to attach a portal to a null host.
* @docs-private
*/
export function throwNullPortalHostError() {
throw Error('Attempting to attach a portal to a null PortalHost');
export function throwNullPortalOutletError() {
throw Error('Attempting to attach a portal to a null PortalOutlet');
}
/**
+8 -8
View File
@@ -3,20 +3,20 @@ The `portals` package provides a flexible system for rendering dynamic content i
### Portals
A `Portal `is a piece of UI that can be dynamically rendered to an open slot on the page.
The "piece of UI" can be either a `Component` or a `TemplateRef` and the "open slot" is
a `PortalHost`.
The "piece of UI" can be either a `Component` or a `TemplateRef` and the "open slot" is
a `PortalOutlet`.
Portals and PortalHosts are low-level building blocks that other concepts, such as overlays, are
Portals and PortalOutlets are low-level building blocks that other concepts, such as overlays, are
built upon.
##### `Portal<T>`
| Method | Description |
| --- | --- |
| `attach(PortalHost): Promise<T>` | Attaches the portal to a host. |
| `attach(PortalOutlet): Promise<T>` | Attaches the portal to a host. |
| `detach(): Promise<void>` | Detaches the portal from its host. |
| `isAttached: boolean` | Whether the portal is attached. |
##### `PortalHost`
##### `PortalOutlet`
| Method | Description |
| --- | --- |
| `attach(Portal): Promise<void>` | Attaches a portal to the host. |
@@ -57,11 +57,11 @@ this.userSettingsPortal = new ComponentPortal(UserSettingsComponent);
```
##### `PortalHostDirective`
Used to add a portal host to a template. `PortalHostDirective` *is* a `PortalHost`.
##### `PortalOutletDirective`
Used to add a portal outlet to a template. `PortalOutletDirective` *is* a `PortalOutlet`.
Usage:
```html
<!-- Attaches the `userSettingsPortal` from the previous example. -->
<ng-template [cdkPortalHost]="userSettingsPortal"></ng-template>
<ng-template [cdkPortalOutlet]="userSettingsPortal"></ng-template>
```
+24 -24
View File
@@ -13,9 +13,9 @@ import {
TemplateRef
} from '@angular/core';
import {CommonModule} from '@angular/common';
import {TemplatePortalDirective, PortalHostDirective, PortalModule} from './portal-directives';
import {TemplatePortalDirective, PortalOutletDirective, PortalModule} from './portal-directives';
import {Portal, ComponentPortal, TemplatePortal} from './portal';
import {DomPortalHost} from './dom-portal-host';
import {DomPortalOutlet} from './dom-portal-outlet';
describe('Portals', () => {
@@ -28,7 +28,7 @@ describe('Portals', () => {
TestBed.compileComponents();
}));
describe('PortalHostDirective', () => {
describe('PortalOutletDirective', () => {
let fixture: ComponentFixture<PortalTestApp>;
beforeEach(() => {
@@ -71,7 +71,7 @@ describe('Portals', () => {
// using TemplatePortal.attach method to set context
testAppComponent.selectedPortal = undefined;
fixture.detectChanges();
templatePortal.attach(testAppComponent.portalHost, {$implicit: {status: 'rotten'}});
templatePortal.attach(testAppComponent.portalOutlet, {$implicit: {status: 'rotten'}});
fixture.detectChanges();
// Expect that the content of the attached portal is present and context given via the
// attach method is projected
@@ -90,7 +90,7 @@ describe('Portals', () => {
// context, the latter should take precedence:
testAppComponent.selectedPortal = undefined;
fixture.detectChanges();
templatePortal.attach(testAppComponent.portalHost, {$implicit: {status: 'rotten'}});
templatePortal.attach(testAppComponent.portalOutlet, {$implicit: {status: 'rotten'}});
fixture.detectChanges();
// Expect that the content of the attached portal is present and and context given via the
// attach method is projected and get precedence over constructor context
@@ -223,32 +223,32 @@ describe('Portals', () => {
testAppComponent.selectedPortal = new ComponentPortal(PizzaMsg);
fixture.detectChanges();
expect(testAppComponent.portalHost.hasAttached()).toBe(true);
expect(testAppComponent.portalHost.portal).toBe(testAppComponent.selectedPortal);
expect(testAppComponent.portalOutlet.hasAttached()).toBe(true);
expect(testAppComponent.portalOutlet.portal).toBe(testAppComponent.selectedPortal);
testAppComponent.selectedPortal = null;
fixture.detectChanges();
expect(testAppComponent.portalHost.hasAttached()).toBe(false);
expect(testAppComponent.portalHost.portal).toBeNull();
expect(testAppComponent.portalOutlet.hasAttached()).toBe(false);
expect(testAppComponent.portalOutlet.portal).toBeNull();
});
it('should set the `portal` when attaching a component portal programmatically', () => {
let testAppComponent = fixture.debugElement.componentInstance;
let portal = new ComponentPortal(PizzaMsg);
testAppComponent.portalHost.attachComponentPortal(portal);
testAppComponent.portalOutlet.attachComponentPortal(portal);
expect(testAppComponent.portalHost.portal).toBe(portal);
expect(testAppComponent.portalOutlet.portal).toBe(portal);
});
it('should set the `portal` when attaching a template portal programmatically', () => {
let testAppComponent = fixture.debugElement.componentInstance;
fixture.detectChanges();
testAppComponent.portalHost.attachTemplatePortal(testAppComponent.cakePortal);
testAppComponent.portalOutlet.attachTemplatePortal(testAppComponent.cakePortal);
expect(testAppComponent.portalHost.portal).toBe(testAppComponent.cakePortal);
expect(testAppComponent.portalOutlet.portal).toBe(testAppComponent.cakePortal);
});
it('should clear the portal reference on destroy', () => {
@@ -257,21 +257,21 @@ describe('Portals', () => {
testAppComponent.selectedPortal = new ComponentPortal(PizzaMsg);
fixture.detectChanges();
expect(testAppComponent.portalHost.portal).toBeTruthy();
expect(testAppComponent.portalOutlet.portal).toBeTruthy();
fixture.destroy();
expect(testAppComponent.portalHost.portal).toBeNull();
expect(testAppComponent.portalOutlet.portal).toBeNull();
});
});
describe('DomPortalHost', () => {
describe('DomPortalOutlet', () => {
let componentFactoryResolver: ComponentFactoryResolver;
let someViewContainerRef: ViewContainerRef;
let someInjector: Injector;
let someFixture: ComponentFixture<any>;
let someDomElement: HTMLElement;
let host: DomPortalHost;
let host: DomPortalOutlet;
let injector: Injector;
let appRef: ApplicationRef;
@@ -284,7 +284,7 @@ describe('Portals', () => {
beforeEach(() => {
someDomElement = document.createElement('div');
host = new DomPortalHost(someDomElement, componentFactoryResolver, appRef, injector);
host = new DomPortalOutlet(someDomElement, componentFactoryResolver, appRef, injector);
someFixture = TestBed.createComponent(ArbitraryViewContainerRefComponent);
someViewContainerRef = someFixture.componentInstance.viewContainerRef;
@@ -397,17 +397,17 @@ describe('Portals', () => {
expect(componentInstance instanceof PizzaMsg)
.toBe(true, 'Expected a PizzaMsg component to be created');
expect(someDomElement.textContent)
.toContain('Pizza', 'Expected the static string "Pizza" in the DomPortalHost.');
.toContain('Pizza', 'Expected the static string "Pizza" in the DomPortalOutlet.');
componentInstance.snack = new Chocolate();
someFixture.detectChanges();
expect(someDomElement.textContent)
.toContain('Chocolate', 'Expected the bound string "Chocolate" in the DomPortalHost');
.toContain('Chocolate', 'Expected the bound string "Chocolate" in the DomPortalOutlet');
host.detach();
expect(someDomElement.innerHTML)
.toBe('', 'Expected the DomPortalHost to be empty after detach');
.toBe('', 'Expected the DomPortalOutlet to be empty after detach');
});
it('should call the dispose function even if the host has no attached content', () => {
@@ -457,12 +457,12 @@ class ArbitraryViewContainerRefComponent {
}
/** Test-bed component that contains a portal host and a couple of template portals. */
/** Test-bed component that contains a portal outlet and a couple of template portals. */
@Component({
selector: 'portal-test',
template: `
<div class="portal-container">
<ng-template [cdkPortalHost]="selectedPortal"></ng-template>
<ng-template [cdkPortalOutlet]="selectedPortal"></ng-template>
</div>
<ng-template cdk-portal>Cake</ng-template>
@@ -481,7 +481,7 @@ class ArbitraryViewContainerRefComponent {
})
class PortalTestApp {
@ViewChildren(TemplatePortalDirective) portals: QueryList<TemplatePortalDirective>;
@ViewChild(PortalHostDirective) portalHost: PortalHostDirective;
@ViewChild(PortalOutletDirective) portalOutlet: PortalOutletDirective;
@ViewChild('templateRef', { read: TemplateRef }) templateRef: TemplateRef<any>;
selectedPortal: Portal<any>;
+17 -17
View File
@@ -15,11 +15,11 @@ import {
Injector
} from '@angular/core';
import {
throwNullPortalHostError,
throwNullPortalOutletError,
throwPortalAlreadyAttachedError,
throwNoPortalAttachedError,
throwNullPortalError,
throwPortalHostAlreadyDisposedError,
throwPortalOutletAlreadyDisposedError,
throwUnknownPortalTypeError
} from './portal-errors';
@@ -30,15 +30,15 @@ export interface ComponentType<T> {
/**
* A `Portal` is something that you want to render somewhere else.
* It can be attach to / detached from a `PortalHost`.
* It can be attach to / detached from a `PortalOutlet`.
*/
export abstract class Portal<T> {
private _attachedHost: PortalHost | null;
private _attachedHost: PortalOutlet | null;
/** Attach this portal to a host. */
attach(host: PortalHost): T {
attach(host: PortalOutlet): T {
if (host == null) {
throwNullPortalHostError();
throwNullPortalOutletError();
}
if (host.hasAttached()) {
@@ -67,10 +67,10 @@ export abstract class Portal<T> {
}
/**
* Sets the PortalHost reference without performing `attach()`. This is used directly by
* the PortalHost when it is performing an `attach()` or `detach()`.
* Sets the PortalOutlet reference without performing `attach()`. This is used directly by
* the PortalOutlet when it is performing an `attach()` or `detach()`.
*/
setAttachedHost(host: PortalHost | null) {
setAttachedHost(host: PortalOutlet | null) {
this._attachedHost = host;
}
}
@@ -85,7 +85,7 @@ export class ComponentPortal<T> extends Portal<ComponentRef<T>> {
/**
* [Optional] Where the attached component should live in Angular's *logical* component tree.
* This is different from where the component *renders*, which is determined by the PortalHost.
* This is different from where the component *renders*, which is determined by the PortalOutlet.
* The origin is necessary when the host is outside of the Angular application context.
*/
viewContainerRef?: ViewContainerRef | null;
@@ -130,11 +130,11 @@ export class TemplatePortal<C> extends Portal<C> {
}
/**
* Attach the the portal to the provided `PortalHost`.
* Attach the the portal to the provided `PortalOutlet`.
* When a context is provided it will override the `context` property of the `TemplatePortal`
* instance.
*/
attach(host: PortalHost, context: C | undefined = this.context): C {
attach(host: PortalOutlet, context: C | undefined = this.context): C {
this.context = context;
return super.attach(host);
}
@@ -147,9 +147,9 @@ export class TemplatePortal<C> extends Portal<C> {
/**
* A `PortalHost` is an space that can contain a single `Portal`.
* A `PortalOutlet` is an space that can contain a single `Portal`.
*/
export interface PortalHost {
export interface PortalOutlet {
attach(portal: Portal<any>): any;
detach(): any;
@@ -161,10 +161,10 @@ export interface PortalHost {
/**
* Partial implementation of PortalHost that handles attaching
* Partial implementation of PortalOutlet that handles attaching
* ComponentPortal and TemplatePortal.
*/
export abstract class BasePortalHost implements PortalHost {
export abstract class BasePortalOutlet implements PortalOutlet {
/** The portal currently attached to the host. */
private _attachedPortal: Portal<any> | null;
@@ -190,7 +190,7 @@ export abstract class BasePortalHost implements PortalHost {
}
if (this._isDisposed) {
throwPortalHostAlreadyDisposedError();
throwPortalOutletAlreadyDisposedError();
}
if (portal instanceof ComponentPortal) {
+5 -1
View File
@@ -7,6 +7,10 @@
*/
export * from './portal';
export * from './dom-portal-host';
export * from './dom-portal-outlet';
export * from './portal-directives';
export * from './portal-injector';
export {DomPortalOutlet as DomPortalHost} from './dom-portal-outlet';
export {PortalOutletDirective as PortalHostDirective} from './portal-directives';
export {PortalOutlet as PortalHost, BasePortalOutlet as BasePortalHost} from './portal';
+3 -3
View File
@@ -1,6 +1,6 @@
<h2> The portal host is here: </h2>
<div class="demo-portal-host">
<ng-template [cdkPortalHost]="selectedPortal"></ng-template>
<h2> The portal outlet is here: </h2>
<div class="demo-portal-outlet">
<ng-template [cdkPortalOutlet]="selectedPortal"></ng-template>
</div>
<button type="button" (click)="selectedPortal = programmingJoke">
+1 -1
View File
@@ -1,4 +1,4 @@
.demo-portal-host {
.demo-portal-outlet {
margin-bottom: 10px;
padding: 10px;
border: 1px dashed black;
+1 -1
View File
@@ -1 +1 @@
<ng-template cdkPortalHost></ng-template>
<ng-template cdkPortalOutlet></ng-template>
+10 -10
View File
@@ -22,9 +22,9 @@ import {
import {animate, AnimationEvent, state, style, transition, trigger} from '@angular/animations';
import {DOCUMENT} from '@angular/platform-browser';
import {
BasePortalHost,
BasePortalOutlet,
ComponentPortal,
PortalHostDirective,
PortalOutletDirective,
TemplatePortal
} from '@angular/cdk/portal';
import {FocusTrap, FocusTrapFactory} from '@angular/cdk/a11y';
@@ -33,7 +33,7 @@ import {MatDialogConfig} from './dialog-config';
/**
* Throws an exception for the case when a ComponentPortal is
* attached to a DomPortalHost without an origin.
* attached to a DomPortalOutlet without an origin.
* @docs-private
*/
export function throwMatDialogContentAlreadyAttachedError() {
@@ -78,9 +78,9 @@ export function throwMatDialogContentAlreadyAttachedError() {
'(@slideDialog.done)': '_onAnimationDone($event)',
},
})
export class MatDialogContainer extends BasePortalHost {
/** The portal host inside of this container into which the dialog content will be loaded. */
@ViewChild(PortalHostDirective) _portalHost: PortalHostDirective;
export class MatDialogContainer extends BasePortalOutlet {
/** The portal outlet inside of this container into which the dialog content will be loaded. */
@ViewChild(PortalOutletDirective) _portalOutlet: PortalOutletDirective;
/** The class that traps and manages focus within the dialog. */
private _focusTrap: FocusTrap;
@@ -117,12 +117,12 @@ export class MatDialogContainer extends BasePortalHost {
* @param portal Portal to be attached as the dialog content.
*/
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
if (this._portalHost.hasAttached()) {
if (this._portalOutlet.hasAttached()) {
throwMatDialogContentAlreadyAttachedError();
}
this._savePreviouslyFocusedElement();
return this._portalHost.attachComponentPortal(portal);
return this._portalOutlet.attachComponentPortal(portal);
}
/**
@@ -130,12 +130,12 @@ export class MatDialogContainer extends BasePortalHost {
* @param portal Portal to be attached as the dialog content.
*/
attachTemplatePortal<C>(portal: TemplatePortal<C>): EmbeddedViewRef<C> {
if (this._portalHost.hasAttached()) {
if (this._portalOutlet.hasAttached()) {
throwMatDialogContentAlreadyAttachedError();
}
this._savePreviouslyFocusedElement();
return this._portalHost.attachTemplatePortal(portal);
return this._portalOutlet.attachTemplatePortal(portal);
}
/** Moves the focus inside the focus trap. */
+1 -1
View File
@@ -1 +1 @@
<ng-template cdkPortalHost></ng-template>
<ng-template cdkPortalOutlet></ng-template>
+7 -7
View File
@@ -28,9 +28,9 @@ import {
AnimationEvent,
} from '@angular/animations';
import {
BasePortalHost,
BasePortalOutlet,
ComponentPortal,
PortalHostDirective,
PortalOutletDirective,
} from '@angular/cdk/portal';
import {first} from 'rxjs/operators';
import {AnimationCurves, AnimationDurations} from '@angular/material/core';
@@ -71,12 +71,12 @@ export const HIDE_ANIMATION =
])
],
})
export class MatSnackBarContainer extends BasePortalHost implements OnDestroy {
export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy {
/** Whether the component has been destroyed. */
private _destroyed = false;
/** The portal host inside of this container into which the snack bar content will be loaded. */
@ViewChild(PortalHostDirective) _portalHost: PortalHostDirective;
/** The portal outlet inside of this container into which the snack bar content will be loaded. */
@ViewChild(PortalOutletDirective) _portalOutlet: PortalOutletDirective;
/** Subject for notifying that the snack bar has exited from view. */
_onExit: Subject<any> = new Subject();
@@ -100,7 +100,7 @@ export class MatSnackBarContainer extends BasePortalHost implements OnDestroy {
/** Attach a component portal as content to this snack bar container. */
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
if (this._portalHost.hasAttached()) {
if (this._portalOutlet.hasAttached()) {
throw Error('Attempting to attach snack bar content after content is already attached');
}
@@ -120,7 +120,7 @@ export class MatSnackBarContainer extends BasePortalHost implements OnDestroy {
this._renderer.addClass(this._elementRef.nativeElement, 'mat-snack-bar-top');
}
return this._portalHost.attachComponentPortal(portal);
return this._portalOutlet.attachComponentPortal(portal);
}
/** Attach a template portal as content to this snack bar container. */
+1 -1
View File
@@ -2,5 +2,5 @@
[@translateTab]="_position"
(@translateTab.start)="_onTranslateTabStarted($event)"
(@translateTab.done)="_onTranslateTabComplete($event)">
<ng-template cdkPortalHost></ng-template>
<ng-template cdkPortalOutlet></ng-template>
</div>
+3 -3
View File
@@ -156,16 +156,16 @@ describe('MatTabBody', () => {
it('should attach the content when centered and detach when not', fakeAsync(() => {
fixture.componentInstance.position = 1;
fixture.detectChanges();
expect(fixture.componentInstance.tabBody._portalHost.hasAttached()).toBe(false);
expect(fixture.componentInstance.tabBody._portalOutlet.hasAttached()).toBe(false);
fixture.componentInstance.position = 0;
fixture.detectChanges();
expect(fixture.componentInstance.tabBody._portalHost.hasAttached()).toBe(true);
expect(fixture.componentInstance.tabBody._portalOutlet.hasAttached()).toBe(true);
fixture.componentInstance.position = 1;
fixture.detectChanges();
flushMicrotasks(); // Finish animation and let it detach in animation done handler
expect(fixture.componentInstance.tabBody._portalHost.hasAttached()).toBe(false);
expect(fixture.componentInstance.tabBody._portalOutlet.hasAttached()).toBe(false);
}));
});
+6 -6
View File
@@ -27,7 +27,7 @@ import {
transition,
AnimationEvent,
} from '@angular/animations';
import {TemplatePortal, PortalHostDirective} from '@angular/cdk/portal';
import {TemplatePortal, PortalOutletDirective} from '@angular/cdk/portal';
import {Directionality, Direction} from '@angular/cdk/bidi';
@@ -87,8 +87,8 @@ export type MatTabBodyOriginState = 'left' | 'right';
]
})
export class MatTabBody implements OnInit, AfterViewChecked {
/** The portal host inside of this container into which the tab body content will be loaded. */
@ViewChild(PortalHostDirective) _portalHost: PortalHostDirective;
/** The portal outlet inside of this container into which the tab body content will be loaded. */
@ViewChild(PortalOutletDirective) _portalOutlet: PortalOutletDirective;
/** Event emitted when the tab begins to animate towards the center as the active tab. */
@Output() _onCentering: EventEmitter<number> = new EventEmitter<number>();
@@ -144,8 +144,8 @@ export class MatTabBody implements OnInit, AfterViewChecked {
* content if it is not already attached.
*/
ngAfterViewChecked() {
if (this._isCenterPosition(this._position) && !this._portalHost.hasAttached()) {
this._portalHost.attach(this._content);
if (this._isCenterPosition(this._position) && !this._portalOutlet.hasAttached()) {
this._portalOutlet.attach(this._content);
}
}
@@ -158,7 +158,7 @@ export class MatTabBody implements OnInit, AfterViewChecked {
_onTranslateTabComplete(e: AnimationEvent) {
// If the end state is that the tab is not centered, then detach the content.
if (!this._isCenterPosition(e.toState) && !this._isCenterPosition(this._position)) {
this._portalHost.detach();
this._portalOutlet.detach();
}
// If the transition to the center is complete, emit an event.
+1 -1
View File
@@ -16,7 +16,7 @@
<!-- If there is a label template, use it. -->
<ng-template [ngIf]="tab.templateLabel">
<ng-template [cdkPortalHost]="tab.templateLabel"></ng-template>
<ng-template [cdkPortalOutlet]="tab.templateLabel"></ng-template>
</ng-template>
<!-- If there is not a label template, fall back to the text label. -->