相关文章推荐
长情的打火机  ·  Android ...·  1 年前    · 
完美的皮带  ·  八、TabLayout - 简书·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I´m working in a project where i need to display more 1000 records and was think in use virtual scroll from the angular material CDK but for some reason i get this error: Error: CdkVirtualScrollViewport is already attached. .

Template

<div class="news-feeds-wrapper">
  <div class="news-feeds-icon" *ngIf="configService.config.showNewsFeeds" (click)="toggleNewsFeeds()">
    <span *ngIf="platform.EDGE || platform.TRIDENT" class="icon-hype-notification_important"></span>
    <mat-icon *ngIf="!platform.EDGE && !platform.TRIDENT">notification_important</mat-icon>
  <cdk-virtual-scroll-viewport itemSize="50">
    <div class="news-feeds-list" [ngClass]="{'open': newsFeedOpen}">
      <div *cdkVirtualFor="let group of newsFeeds">
        <div class="time" *ngIf="group.values.length > 0">{{group.type}}</div>
        <div class="news-feed" *cdkVirtualFor="let item of group.values | async">
          <div class="header">
            <i [ngSwitch]="item.action_type">
              <mat-icon *ngSwitchCase="'Task Assignment'">swap_horiz</mat-icon>
              <mat-icon *ngSwitchCase="'User Mention'">chat</mat-icon>
              <mat-icon *ngSwitchCase="'Task Deleted'">no_sim</mat-icon>
            <span>{{item.action_type}}</span>
            <mat-icon class="deleted-news-feed" (click)="deletedNewsFeeds(group.values, item)">clear</mat-icon>
          <div class="news-feed-content">
            <div class="info-content">
              <p class="project">{{item.project}}</p>
              <p class="taskboard">{{item.task_board}}</p>
              <p class="board-item">{{item.task_board_item}}</p>
            <div class="avatar">
  </cdk-virtual-scroll-viewport>

Component

@Component({
  selector: 'news-feeds',
  templateUrl: '../templates/news-feed.component.html',
  styleUrls: ['../../assets/scss/news-feeds.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
export class NewsFeedsComponent implements OnInit {
  public newsFeedOpen = false;
  public newsFeeds: Array<any> = [];
  @HostListener('document:click', ['$event'])
  closeNewsFeeds(event) {
    if (this.newsFeedOpen && event.target.localName != 'mat-icon') {
      this.newsFeedOpen = false;
  constructor(public platform: Platform, public configService: HypeConfigService, private cd: ChangeDetectorRef, private log: LoggingService, private backlogService: BacklogTaskService) {
  ngOnInit() {
  toggleNewsFeeds() {
    this.backlogService.getNewsFeeds().subscribe(
      (response) => {
        this.newsFeedOpen = !this.newsFeedOpen;
        this.newsFeeds = response;
        this.cd.markForCheck();
      (error) => {
        this.log.error(`Error loading the news feeds: ${error}`);
  deletedNewsFeeds(group: Array<any>, newsFeed: any) {
    const index = group.findIndex((i) => i.id === newsFeed.id);
    group.splice(index, 1);

so for some reason is telling me that CdkVirtualScrollViewport is attached already but i not using in any other place on my application. stackblitz

The issue is due to the fact that you used *cdkVirtualFor twice, one inside the other... To resolve, I made 2 changes;

  • app.component.html: used *ngFor instead of *cdkVirtualFor, so
  • <div class="news-feed" *ngFor="let item of group.values"> instead of
  • <div class="news-feed" *cdkVirtualFor="let item of group.values">
  • app.component.css: Added cdk-virtual-scroll-viewport { height:400px; } because the height is zero by default
  • HTML changes & CSS addition in the code snippet below

    cdk-virtual-scroll-viewport {
      height: 400px;
    
    <div class="news-feeds-wrapper">
      <div class="news-feeds-list open">
        <cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
          <div *cdkVirtualFor="let group of newsfeeds">
            <div class="time">{{group.type}}</div>
            <div class="news-feed" *ngFor="let item of group.values">
              <div class="header">
                <span>{{item.action_type}}</span>
                <mat-icon class="deleted-news-feed">clear</mat-icon>
              <div class="news-feed-content">
                <div class="info-content">
                  <p class="project">{{item.project}}</p>
                  <p class="taskboard">{{item.task_board}}</p>
                  <p class="board-item">{{item.task_board_item}}</p>
                <div class="avatar">
        </cdk-virtual-scroll-viewport>
                    I guess you are right, if this is the case i think there is no way to put the *cdkVirtualFor in the second iteration instead of the first one...
    – Miguel Frias
                    Jan 30, 2019 at 11:39
                    Thanks for the upVote, You can test this in your actual code also... I'd appreciate if you mark the answer as accepted also.
    – Akber Iqbal
                    Jan 30, 2019 at 11:41
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.