代码之家  ›  专栏  ›  技术社区  ›  Sidharth Bajpai

Angular:cdk虚拟滚动视口-滚动窗口属性在Angular ssr(通用)中不起作用,给出错误-未定义文档

  •  2
  • Sidharth Bajpai  · 技术社区  · 2 年前

    在Angular SSR应用程序中使用cdk虚拟滚动视口并添加scrollWindow属性时,我收到以下错误:-

    document is not defined
        at _CdkVirtualScrollableWindow (...\test_cdk_scroll_ssr\node_modules\@angular\cdk\fesm2022\scrolling.mjs:1659:26)
        at NodeInjectorFactory.CdkVirtualScrollableWindow_Factory (...\test_cdk_scroll_ssr\node_modules\@angular\cdk\fesm2022\scrolling.mjs:1667:14)
        at getNodeInjectable (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:5984:44)
        at searchTokensOnInjector (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:5911:16)
        at lookupTokenUsingNodeInjector (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:5860:34)
        at getOrCreateInjectable (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:5772:23)
        at ɵɵdirectiveInject (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:11050:19)
        at ɵɵinject (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:1106:42)
        at NodeInjectorFactory.factory (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:3325:29)
        at getNodeInjectable (...\test_cdk_scroll_ssr\node_modules\@angular\core\fesm2022\core.mjs:5984:44
    

    我遵循 official example 的scrollWindow属性,它给了我上面的错误。此示例适用于非SSR角度应用程序。

    我的代码 (与示例中完全相同)

    app.component.ts:-

    import { ChangeDetectionStrategy, Component } from '@angular/core';
    import {ScrollingModule} from '@angular/cdk/scrolling';
    
    @Component({
      selector: 'app-root',
      styleUrl: './app.component.scss',
      templateUrl: './app.component.html',
      changeDetection: ChangeDetectionStrategy.OnPush,
      standalone: true,
      imports: [ScrollingModule]
    })
    export class AppComponent {
      items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
    }
    
    

    app.component.html

    <div class="example-header">Content before</div>
    <cdk-virtual-scroll-viewport scrollWindow itemSize="50">
      <div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
    </cdk-virtual-scroll-viewport>
    <div class="example-footer">Content after</div>
    

    app.component.scss:-

    .example-item {
        height: 50px;
      }
      
      .example-header,
      .example-footer {
        height: 100px;
        background: lightgray;
      }
    

    也许它不起作用,因为窗口在服务器端不可用?

    有没有办法让scrollWindow属性在Angular SSR应用程序中工作?谢谢

    1 回复  |  直到 2 年前
        1
  •  2
  •   Naren Murali    2 年前

    是的,只在浏览器上进行虚拟滚动渲染时,我们可以使用 isPlatformBrowser 并解决它!

    import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
    import { NgIf } from '@angular/common';
    import {ScrollingModule} from '@angular/cdk/scrolling';
    
    @Component({
      selector: 'app-root',
      styleUrl: './app.component.scss',
      templateUrl: './app.component.html',
      changeDetection: ChangeDetectionStrategy.OnPush,
      standalone: true,
      imports: [ScrollingModule, NgIf]
    })
    export class AppComponent {
      items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
      isBrowser: boolean;
    
      constructor( @Inject(PLATFORM_ID) platformId: Object) {
          this.isBrowser = isPlatformBrowser(platformId);
      }
    }
    

    HTML

    <ng-container *ngIf="isBrowser">
        <div class="example-header">Content before</div>
        <cdk-virtual-scroll-viewport scrollWindow itemSize="50">
          <div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
        </cdk-virtual-scroll-viewport>
        <div class="example-footer">Content after</div>
    </ng-container>
    

    顺便说一句,该组件使用 window 或 document 对象,因此在服务器上渲染毫无意义,这是一个仅限浏览器的功能,因为使用了 窗 或 文件 !

    推荐文章