代码之家  ›  专栏  ›  技术社区  ›  Sefat Anam

在ng模板内访问CdkVirtualScrollViewport时出现View Child错误

  •  0
  • Sefat Anam  · 技术社区  · 2 年前

    我使用了角度CDK叠加,在我的叠加中,我有一些选项是通过虚拟滚动进行包裹,现在我想通过View Child访问我的组件中的虚拟滚动,但不断出现错误。我找不到任何解决方案。这是我的代码示例,

    HTML:
    
      <ng-template cdkConnectedOverlay cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop" [cdkConnectedOverlayHasBackdrop]="true" [cdkConnectedOverlayOrigin]="trigger" [cdkConnectedOverlayOpen]="isMenuOpen" (detach)="isMenuOpen = false" (backdropClick)="isMenuOpen = false">
    
              <cdk-virtual-scroll-viewport itemSize="50">
                <mat-option style=";height: 50px;" (click)="optionClicked($event, data)" *cdkVirtualFor="let data of filteredData;">
                  <div (click)="optionClicked($event, data)">
                    <mat-checkbox [checked]="data.selected">
                      {{ data.skillName }}
                    </mat-checkbox>
                  </div>
                </mat-option>
              </cdk-virtual-scroll-viewport>
    
    </ng-template>
    
    
    TS:
    
    @ViewChild(CdkVirtualScrollViewport) cdkVirtualScrollViewport: CdkVirtualScrollViewport;
    
    
      ngAfterViewInit() {
        
         this.cdkVirtualScrollViewport.elementScrolled().pipe(
           map(() => this.cdkVirtualScrollViewport.measureScrollOffset('bottom')),
           pairwise(),
           filter(([y1, y2]) => (y2 < y1) && (y2 < 70)),
           tap(() => this.isLoading = true),
           switchMap((_) => {..API CALL..})).subscribe(...)
    ....
    }
    
    ERROR:
    
    ERROR TypeError: Cannot read properties of undefined (reading 'elementScrolled')
        at MultiselectAutocompleteComponent.ngAfterViewInit (multiselect-autocomplete.component.ts:212:36)
        at callHook (core.mjs:2449:22)
        at callHooks (core.mjs:2418:17)
        at executeInitAndCheckHooks (core.mjs:2369:9)
        at refreshView (core.mjs:10413:21)
        at refreshComponent (core.mjs:11401:13)
        at refreshChildComponents (core.mjs:10132:9)
        at refreshView (core.mjs:10392:13)
        at refreshEmbeddedViews (core.mjs:11355:17)
        at refreshView (core.mjs:10366:9)
    
    

    我想要AfterViewInit中的CDK虚拟滚动视图端口引用,这样我就可以获得底部滚动事件。因为我不想一次获取数千个响应,所以我想在用户到达底部时调用API。

    0 回复  |  直到 2 年前
        1
  •  1
  •   Matthieu Riegler    2 年前

    这个 ViewChild 将仅在渲染模板后定义。

    您可以将属性设置为setter,以便在 CdkVirtualScrollViewport 已初始化。

      @ViewChild(CdkVirtualScrollViewport) set viewPort(vp: CdkVirtualScrollViewport) {
         if(vp) {
           this.cdkVirtualScrollViewport.elementScrolled()
           ...
         }
      } ;
    
        2
  •  0
  •   W.S.    2 年前

    您正在使用 <ng-template> 要素

    With <ng-template>, you can define template content that is only being rendered by Angular when you, whether directly or indirectly, specifically instruct it to do so, allowing you to have full control over how and when the content is displayed.

    除非显式呈现模板,否则内容将不会在DOM中呈现,ViewChild将无法拾取它,即使AfterViewInit也无法拾取。

    用包起来 <ng-container> 相反