mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(overlay): unable to change CdkConnectedOverlay origin dynamically (#9358)
Fixes the `CdkConnectedOverlay` not handling changes of its `origin` after it's opened for the first time. Fixes #9353.
This commit is contained in:
committed by
Jeremy Elbourn
parent
69270efb7e
commit
df447674a9
@@ -20,11 +20,7 @@ describe('Overlay directives', () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [OverlayModule],
|
||||
declarations: [ConnectedOverlayDirectiveTest, ConnectedOverlayPropertyInitOrder],
|
||||
providers: [
|
||||
{provide: Directionality, useFactory: () => {
|
||||
return dir = {value: 'ltr'};
|
||||
}}
|
||||
],
|
||||
providers: [{provide: Directionality, useFactory: () => dir = {value: 'ltr'}}],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -250,6 +246,28 @@ describe('Overlay directives', () => {
|
||||
.toBe('105px', `Expected overlay directive to reflect new offsetY if it changes.`);
|
||||
});
|
||||
|
||||
it('should be able to update the origin after init', () => {
|
||||
const testComponent = fixture.componentInstance;
|
||||
|
||||
testComponent.isOpen = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
let triggerRect = fixture.nativeElement.querySelector('#trigger').getBoundingClientRect();
|
||||
let overlayRect = getPaneElement().getBoundingClientRect();
|
||||
|
||||
expect(Math.floor(triggerRect.left)).toBe(Math.floor(overlayRect.left));
|
||||
expect(Math.floor(triggerRect.bottom)).toBe(Math.floor(overlayRect.top));
|
||||
|
||||
testComponent.triggerOverride = testComponent.otherTrigger;
|
||||
fixture.detectChanges();
|
||||
|
||||
triggerRect = fixture.nativeElement.querySelector('#otherTrigger').getBoundingClientRect();
|
||||
overlayRect = getPaneElement().getBoundingClientRect();
|
||||
|
||||
expect(Math.floor(triggerRect.left)).toBe(Math.floor(overlayRect.left));
|
||||
expect(Math.floor(triggerRect.bottom)).toBe(Math.floor(overlayRect.top));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('outputs', () => {
|
||||
@@ -302,9 +320,11 @@ describe('Overlay directives', () => {
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<button cdk-overlay-origin #trigger="cdkOverlayOrigin">Toggle menu</button>
|
||||
<button cdk-overlay-origin id="trigger" #trigger="cdkOverlayOrigin">Toggle menu</button>
|
||||
<button cdk-overlay-origin id="otherTrigger" #otherTrigger="cdkOverlayOrigin">Toggle menu</button>
|
||||
|
||||
<ng-template cdk-connected-overlay [open]="isOpen" [width]="width" [height]="height"
|
||||
[origin]="trigger"
|
||||
[cdkConnectedOverlayOrigin]="triggerOverride || trigger"
|
||||
[hasBackdrop]="hasBackdrop" backdropClass="mat-test-class"
|
||||
(backdropClick)="backdropClicked=true" [offsetX]="offsetX" [offsetY]="offsetY"
|
||||
(positionChange)="positionChangeHandler($event)" (attach)="attachHandler()"
|
||||
@@ -313,13 +333,18 @@ describe('Overlay directives', () => {
|
||||
</ng-template>`,
|
||||
})
|
||||
class ConnectedOverlayDirectiveTest {
|
||||
@ViewChild(CdkConnectedOverlay) connectedOverlayDirective: CdkConnectedOverlay;
|
||||
@ViewChild('trigger') trigger: CdkOverlayOrigin;
|
||||
@ViewChild('otherTrigger') otherTrigger: CdkOverlayOrigin;
|
||||
|
||||
isOpen = false;
|
||||
width: number | string;
|
||||
height: number | string;
|
||||
minWidth: number | string;
|
||||
minHeight: number | string;
|
||||
offsetX: number = 0;
|
||||
offsetY: number = 0;
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
triggerOverride: CdkOverlayOrigin;
|
||||
hasBackdrop: boolean;
|
||||
backdropClicked = false;
|
||||
positionChangeHandler = jasmine.createSpy('positionChangeHandler');
|
||||
@@ -329,8 +354,6 @@ class ConnectedOverlayDirectiveTest {
|
||||
});
|
||||
detachHandler = jasmine.createSpy('detachHandler');
|
||||
attachResult: HTMLElement;
|
||||
|
||||
@ViewChild(CdkConnectedOverlay) connectedOverlayDirective: CdkConnectedOverlay;
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -256,6 +256,14 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if ((changes['origin'] || changes['_deprecatedOrigin']) && this._position) {
|
||||
this._position.setOrigin(this.origin.elementRef);
|
||||
|
||||
if (this.open) {
|
||||
this._position.apply();
|
||||
}
|
||||
}
|
||||
|
||||
if (changes['open'] || changes['_deprecatedOpen']) {
|
||||
this.open ? this._attachOverlay() : this._detachOverlay();
|
||||
}
|
||||
|
||||
@@ -265,6 +265,15 @@ export class ConnectedPositionStrategy implements PositionStrategy {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the origin element, relative to which to position the overlay.
|
||||
* @param origin Reference to the new origin element.
|
||||
*/
|
||||
setOrigin(origin: ElementRef): this {
|
||||
this._origin = origin.nativeElement;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the horizontal (x) "start" dimension based on whether the overlay is in an RTL context.
|
||||
* @param rect
|
||||
|
||||
Reference in New Issue
Block a user