附加后动态更改 Angular material 叠加位置
Change Angular material overlay position dynamically after attaching
有一些叠加层需要在 window-resize
事件后重新定位。
当前配置的初始值 PositionStrategy
具有依赖于外部变量的逻辑 以类似于 CSS Grid / Flexbox 行为来对齐 Overalys。
这个material2 github issue好像只能用OverlayRef.dispose()
=> OverlayRef.create()
.
有没有满足以下条件的解决方案:
- 可以使用非静态值更新位置。
- 不破坏组件实例。
最好能够从服务中调用,而不是 OverlayRef
的组件实例。
为清楚起见编辑 1:
鉴于以下 PositionStrategy
,OverlayRef.updatePosition()
似乎不适用,因为需要重新计算 px。 *注 window.innerWidth
private setChannelPosition(): PositionStrategy {
const chatWidth = 280;
const chatSpace = 5;
const distanceFromEdge = 80;
const existingModalCount = this.channelModals.size;
const numModalsCanFit =
Math.floor((window.innerWidth - 2 * distanceFromEdge) / (chatWidth + chatSpace));
const distFromRight =
distanceFromEdge + ((existingModalCount % numModalsCanFit) * (chatWidth + chatSpace));
return this.overlay.position().global().bottom('0px').right(`${distFromRight}px`);
}
编辑 2:
模态是瞬态的。因此 flexibleConnectedTo()
的解决方案似乎不适用,因为用户可能会或可能不会以任何顺序关闭任何模态。
假设您在制作 OverlayConfig
时只调用 setChannelPosition()
一次,例如:
export class MyComponent implements OnInit {
private overlayRef: OverlayRef;
constructor(
private overlay: Overlay
) { }
public ngOnInit(): void {
this.createOverlay();
}
@HostListener('window:resize')
public onResize(): void {
this.overlayRef.updatePosition();
}
private setChannelPosition(): PositionStrategy {
const chatWidth = 280;
const chatSpace = 5;
const distanceFromEdge = 80;
const existingModalCount = this.channelModals.size;
const numModalsCanFit = Math.floor((window.innerWidth - 2 * distanceFromEdge) / (chatWidth + chatSpace));
const distFromRight = distanceFromEdge + ((existingModalCount % numModalsCanFit) * (chatWidth + chatSpace));
return this.overlay.position().global().bottom('0px').right(`${distFromRight}px`);
}
private createOverlay() {
const config = new OverlayConfig({
positionStrategy: this.setChannelPosition()
});
this.overlayRef = this.overlay.create(config);
this.overlayRef.attach(/* template or component*/);
}
}
所以行 this.overlay.position().global().bottom('0px').right(
${distFromRight}px);
只运行一次创建一个 GlobalPositionStrategy
底部 0px 和 rigth 是 distFromRight
的值当时。
OverlayRef.updatePosition()
调用 PositionStrategy.apply()
,GlobalPositionStrategy
实现并根据其属性简单地应用 css 值(在本例中是底部 0px,rigth 是任何值distFromRight
当 setChannelPosition()
运行).
解决方案是让 PositionStrategy
在 PositionStrategy.apply()
上重新计算。
class MyPositionStrategy implements PositionStrategy {
public apply(): void {
/* recalculates */
}
}
const config = new OverlayConfig({
positionStrategy: instanceOfMyPositionStrategy
});
或
通过调用 OverlayRef.updatePositionStrategy()
new 将调用 OverlayRef.updatePosition()
之前的 PositionStrategy
更改为 angular material 7 我认为 。
@HostListener('window:resize')
public onResize(): void {
this.overlayRef.updatePositionStrategy(this.setChannelPosition());
this.overlayRef.updatePosition();
}
因此 setChannelPosition()
运行并且 PositionStrategy
每次 window 调整大小时都会更改。
注:
有一个像
这样的旧解决方案
@HostListener('window:resize')
public onResize(): void {
this.overlayRef.getConfig().positionStrategy = this.setChannelPosition();
this.overlayRef.updatePosition();
}
但是 getConfig().positionStrategy
现在是只读的并且不起作用
有一些叠加层需要在 window-resize
事件后重新定位。
当前配置的初始值 PositionStrategy
具有依赖于外部变量的逻辑 以类似于 CSS Grid / Flexbox 行为来对齐 Overalys。
这个material2 github issue好像只能用OverlayRef.dispose()
=> OverlayRef.create()
.
有没有满足以下条件的解决方案:
- 可以使用非静态值更新位置。
- 不破坏组件实例。
最好能够从服务中调用,而不是 OverlayRef
的组件实例。
为清楚起见编辑 1:
鉴于以下 PositionStrategy
,OverlayRef.updatePosition()
似乎不适用,因为需要重新计算 px。 *注 window.innerWidth
private setChannelPosition(): PositionStrategy {
const chatWidth = 280;
const chatSpace = 5;
const distanceFromEdge = 80;
const existingModalCount = this.channelModals.size;
const numModalsCanFit =
Math.floor((window.innerWidth - 2 * distanceFromEdge) / (chatWidth + chatSpace));
const distFromRight =
distanceFromEdge + ((existingModalCount % numModalsCanFit) * (chatWidth + chatSpace));
return this.overlay.position().global().bottom('0px').right(`${distFromRight}px`);
}
编辑 2:
模态是瞬态的。因此 flexibleConnectedTo()
的解决方案似乎不适用,因为用户可能会或可能不会以任何顺序关闭任何模态。
假设您在制作 OverlayConfig
时只调用 setChannelPosition()
一次,例如:
export class MyComponent implements OnInit {
private overlayRef: OverlayRef;
constructor(
private overlay: Overlay
) { }
public ngOnInit(): void {
this.createOverlay();
}
@HostListener('window:resize')
public onResize(): void {
this.overlayRef.updatePosition();
}
private setChannelPosition(): PositionStrategy {
const chatWidth = 280;
const chatSpace = 5;
const distanceFromEdge = 80;
const existingModalCount = this.channelModals.size;
const numModalsCanFit = Math.floor((window.innerWidth - 2 * distanceFromEdge) / (chatWidth + chatSpace));
const distFromRight = distanceFromEdge + ((existingModalCount % numModalsCanFit) * (chatWidth + chatSpace));
return this.overlay.position().global().bottom('0px').right(`${distFromRight}px`);
}
private createOverlay() {
const config = new OverlayConfig({
positionStrategy: this.setChannelPosition()
});
this.overlayRef = this.overlay.create(config);
this.overlayRef.attach(/* template or component*/);
}
}
所以行 this.overlay.position().global().bottom('0px').right(
${distFromRight}px);
只运行一次创建一个 GlobalPositionStrategy
底部 0px 和 rigth 是 distFromRight
的值当时。
OverlayRef.updatePosition()
调用 PositionStrategy.apply()
,GlobalPositionStrategy
实现并根据其属性简单地应用 css 值(在本例中是底部 0px,rigth 是任何值distFromRight
当 setChannelPosition()
运行).
解决方案是让 PositionStrategy
在 PositionStrategy.apply()
上重新计算。
class MyPositionStrategy implements PositionStrategy {
public apply(): void {
/* recalculates */
}
}
const config = new OverlayConfig({
positionStrategy: instanceOfMyPositionStrategy
});
或
通过调用 OverlayRef.updatePositionStrategy()
new 将调用 OverlayRef.updatePosition()
之前的 PositionStrategy
更改为 angular material 7 我认为 。
@HostListener('window:resize')
public onResize(): void {
this.overlayRef.updatePositionStrategy(this.setChannelPosition());
this.overlayRef.updatePosition();
}
因此 setChannelPosition()
运行并且 PositionStrategy
每次 window 调整大小时都会更改。
注:
有一个像
这样的旧解决方案@HostListener('window:resize')
public onResize(): void {
this.overlayRef.getConfig().positionStrategy = this.setChannelPosition();
this.overlayRef.updatePosition();
}
但是 getConfig().positionStrategy
现在是只读的并且不起作用