zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Angular 学习笔记 ( CDK - Overlays )

2023-09-27 14:23:56 时间

更新: 2021-01-20

在 version 11 的版本里, excludeFromOutsideClick 已经被拿掉了. 因为 ng mat team 认为这个接口太死板了, 干脆让开发者自己去实现. 

今天遇到一个鸟问题, 之前我有用 overlay 做一个 small modal, 通过 backdrop 来关闭, 现在改成通过 outside overlay click 来关闭

 

 

 

 依据 ng 的执行假设你有 3 个 overlay 在场上, 它会从最后一个 (第 3 个开始 loop)

然后看这个 overlay 有没有监听 outside click, 没有的话就 skip 

也就是说, 有监听 outside click 和没有监听的是不相容的 

距离我做的 small modal 就是 outside click, 如果里面放了一个 autocomplete 就坏掉了.

因为 ng 的 autocomplete 并没有使用 outside click ... 

目前没有正确的解决方案. hacking 的 way 就是可以通过 OverlayOutsideClickDispatcher 获取到所有 overlay 然后自行在判断一次. 

for backdrop 也是一样会影响到 outside click 哦

 

 

 

 

 

更新: 2020-07-26

好久没有看到新功能了 

10.1.0 overlay 多了一个新功能, 就是在没有 backdrop 的情况下也能通过全局点击关掉 overlay 

以前比较常见的方案是, 当 overlay 出现后, 做一个透明的 backdrop, 当用户点击 backdrop 就关闭 overlay

这个 backdrop 是透明的, 看不见但是却摸得到, 这样不一定好, 有时候希望完全摸不到.

主要是新增了 OverlayOutsideClickDispatcher 服务.

overlay attach 的时候, 会添加自己到 dispatcher 列队里, 这个 dispatcher 负责监听 body click

click 之后通过判断点击事件是否在 overlay 里面 (里面就 skip) 来除非响应事件 (比如关闭 overlay 等)

监听的方式时 overlayRef.outsidePointerEvents().subscribe()
这里的方式和 scroll dispatcher 的设计时一样的. 我们也可以手动添加 dispatcher.add(element) 这样
此外还有一个 excludeFromOutsideClick 接口可以来表示某些 element 不作为 outside click
 

 

 

 

 

更新 : 2019-07-03

https://netbasal.com/creating-powerful-components-with-angular-cdk-2cef53d81cea

 

更新 : 2018-01-30 

ng 的 overlap 在关闭的时候对 backdrop 做了一个 style pointer 

目的是让 backdrop 不被 2 次点击, 但是呢,  css pointerEvent 'none' 也有一个穿透的效果,就是说, backdrop 还没完全关上时, 其后面的按钮是可以被点击到的. 

这个需要注意,因为可能你并不想这样。 

另外一个要说的是, overlap 是可以打开多个的. 通过多个 overlapRef 去自行做管理. 所以请把 overlapRef 收好. 

 

 

https://blog.thoughtram.io/angular/2017/11/20/custom-overlays-with-angulars-cdk.html

https://blog.thoughtram.io/angular/2017/11/27/custom-overlays-with-angulars-cdk-part-two.html

这 2 篇已经教的很清楚了. 

ng overlays 是通过 service + dynamic component or template 来实现的

dynamic component 和 template (outlet) 如何使用之前有讲过了.

ng overlays 唯一一个我觉得需要提别注意的地方是它的关闭

如果你直接调用 displose 的话,element 会马上被删除, 体验可能不是很好。

如果要加个 animation 并不容易。

<ng-overlay-div>

  <背景>

  <ng-frame>

    <我们的 dynamic component>

  </ng-frame>

</ng-overlay-div>

overlay 的结构大概是这样的 ng 在 displose 的时候会洗掉 frame and 背景, 重点是它没有调用 animation child 运行.

所以即使我们写 animation 在 dynamic component 也不会触发

依据上面的教程或者看 material dialog 的实现源码的话,你会发现要做 animation 要反过来做.

意思是,你通过设置 aniamation state = 'leave' 然后监听 aniamtion end event 然后才调用 displose 去洗掉 element 

真的是超麻烦的...