首页 > 解决方案 > 带有 ResizeObserver 的 ViewContainerRef 在角度中无法正常工作

问题描述

我正在尝试使用ComponentFactoryResolver根据屏幕大小动态添加和删除组件。

@ViewChild('sidebarContainer', { read: ViewContainerRef }) sidebarContainer: ViewContainerRef;

_handleBodyResize() {
let self = this;
if (typeof ResizeObserver == 'undefined') return;

const obs = new ResizeObserver(entries => {
  let entry = entries[0];

  if ((entry.contentRect.width) < MOBILE_WIDTH) {
    if (this.deviceType !== DeviceType.mobile) {
      this.removeSidebar();

      this.deviceType = DeviceType.mobile;
    }
  } else {
    if (this.deviceType !== DeviceType.desktop) {
      this.addSidebar();

      this.deviceType = DeviceType.desktop;
    }
  };
});

removeSidebar() {
  this.sidebarContainer.clear();
  this.sidebarRef.destroy();
}

addSidebar() {
this.sidebarContainer.clear();
//_cfr is componentFactoryResolver
const compFactory = this._cfr.resolveComponentFactory(this.array[0]);

let comp = this.sidebarContainer.createComponent(compFactory);

this.sidebarRef = comp;
}

和 HTML

<div class="sidebar-container">
<div #sidebarContainer>

</div>

这个 sidebarContainer viewContainerRef 似乎无法保留引用并创建 SidebarComponent 的新实例,只要主体的 with 来自< 768pxto>= 768px并且不删除保存在sidebarRef和事件sidebarContainer.clear()方法中的先前创建的组件不工作

奇怪的是,如果我使用window.addEventListener('resize'...它的话。

是否有一些我不知道的潜在ResizeObserver技术性,有没有办法让它与ResizeObserver一起使用

更新

我忘了提到这一点,但是调整大小观察器中的代码会按时执行并适当地调用这两个函数。

else 部分始终创建 SidebarComponent 的新实例并将其呈现到视图中,但即使在调试时也不会删除先前创建的实例,我可以看到它this.sidebarContainer.clear()并没有未定义,并且分别是 ViewContainerRef 和 ComponentRef 的相关实例。this.sidebarRef.destroysidebarContainersidebarRef

标签: angularangular7

解决方案


Angular 执行更改检测以响应各种触发器。DOM 事件、ajax 请求和计时器/可观察对象将触发 Angular 的更改检测。

窗口resize事件是触发更改检测的 DOM 事件示例。

据我所知,Angular 的变更检测不会ResizeObserver. 因此,您需要明确告诉 Angular 使用以下命令检测更改ChangeDetectorRef.detectChanges()

constructor(private changeDetector: ChangeDetectorRef) {}

ngAfterViewInit() {
  const obs = new ResizeObserver(entries => {
    // Perform updates in response to resize

    // Then tell Angular to detect changes
    this.changeDetector.detectChanges();
  });
  obs.observe(this.resizeDiv.nativeElement);
}

这是一个StackBlitz 示例

如果您只关心视口尺寸的更改,则无需使用ResizeObserver. windowresize事件在所有浏览器中都可以正常工作。


推荐阅读