Javascript 使用angular4中的observable实现angular2虚拟滚动

Javascript 使用angular4中的observable实现angular2虚拟滚动,javascript,html,angular,observable,vertical-scrolling,Javascript,Html,Angular,Observable,Vertical Scrolling,我正在尝试在angular4项目中实现angular2虚拟滚动。首先,有人能确认我在NG4中实现它是否会有问题吗。我认为我不应该,我也没有看到任何相反的通知。其次,我使用的是一个可观察的,而不是NPM angular2虚拟滚动文档中显示的承诺。但是,当我应用虚拟滚动标记时,我的输出没有变化…没有滚动条..显示可观察的数据,但没有滚动。以下是相关代码段: Home.component.html <h1 style="color: #76323f"> {{title}} </h

我正在尝试在angular4项目中实现angular2虚拟滚动。首先,有人能确认我在NG4中实现它是否会有问题吗。我认为我不应该,我也没有看到任何相反的通知。其次,我使用的是一个可观察的,而不是NPM angular2虚拟滚动文档中显示的承诺。但是,当我应用虚拟滚动标记时,我的输出没有变化…没有滚动条..显示可观察的数据,但没有滚动。以下是相关代码段:

Home.component.html

<h1 style="color: #76323f">
  {{title}}
</h1>

<h4>
  {{description}}
</h4>
<h2>Coming Soon....</h2>
<app-events-list [upcomingEvents]="upcomingEvents"></app-events-list>
    <virtual-scroll [items]="items" (update)="upcomingEvents = $event"
    (change)="onlistChange($event)">
     <app-upcomingevent *ngFor="let upcomingEvent of upcomingEvents"[upcomingEvent]="upcomingEvent" [eventItemCss]="'event-item'"></app-upcomingevent>
     <div *ngIf="loading" class="loader">Loading.....</div>
    </virtual-scroll>
<md-card [ngClass]="'event-item'">
  <h4 [ngClass]="'event-title'" [ngStyle]="{'color':'purple'}"> {{upcomingEvent.title}}</h4>    
   <md-card-actions>
    <button md-button>LIKE</button>
    <button md-button>SHARE</button>
   </md-card-actions>
</md-card>
...
<app-events-list [items]="upcomingEvents"></app-events-list>

{{title}}
{{description}}
马上就来。。。。
home.component.ts

import {Component, OnInit,OnDestroy } from '@angular/core';
import {UpcomingEvent}       from './../../interface/upcomingevent';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

export class HomeComponent implements OnInit, OnDestroy {
  upcomingEvents: Array<UpcomingEvent>;
  title = 'Welcome....';
  description='Events promotions....';
  eventServiceSub: Subscription;

  constructor(private eventService: EventService){
    this.upcomingEvents = [];
  }

  ngOnInit() {
    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{this.upcomingEvents=upcomingEvents.slice(0,25);
    });
  }
  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 
}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 upcomingEvents: Array<UpcomingEvent>;

 items=this.upcomingEvents;
 protected buffer: Array<UpcomingEvent> =[];
 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.buffer.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.buffer=upcomingEvents.slice(this.buffer.length,25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
import { Injectable } from '@angular/core';
import {UpcomingEvent} from './../interface/upcomingevent'
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class EventService {

  constructor(private http: Http) { }

  getEvents(): Observable<UpcomingEvent[]>
  {
    return this.http
       .get(`https://jsonplaceholder.typicode.com/posts`)
       .map(response => response.json() as UpcomingEvent[]);

  }
}
import { Component, Input,OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
@Component({
  selector: 'app-upcomingevent',
  templateUrl: './upcomingevent.component.html',
  styleUrls: ['./upcomingevent.component.css']
})
export class UpcomingeventComponent implements OnInit {

 @Input()
 upcomingEvent: UpcomingEvent;

 @Input()
 eventItemCss: string;

  constructor() { }

  ngOnInit() {
    if (!this.upcomingEvent) {
     this.upcomingEvent=<UpcomingEvent> {}; 
     }

    }

}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 items: Array<UpcomingEvent> = [];

 upcomingEvents: Array<UpcomingEvent>;

 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.items.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.items=upcomingEvents.slice(0, this.items.length + 25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
从'@angular/core'导入{Component,OnInit,OnDestroy};
从“/../../interface/UpcomingEvent”导入{UpcomingEvent};
从“/../services/event.service”导入{EventService};
从'rxjs/Subscription'导入{Subscription};
@组成部分({
选择器:“应用程序主页”,
templateUrl:“./home.component.html”,
样式URL:['./home.component.css']
})
导出类HomeComponent实现OnInit、OnDestroy{
upcomingEvents:数组;
标题=‘欢迎……’;
description='Events promotions…';
eventServiceSub:订阅;
构造函数(私有eventService:eventService){
this.upcomingEvents=[];
}
恩戈尼尼特(){
this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{this.upcomingEvents=upcomingEvents.slice(0,25);
});
}
恩贡德斯特罗(){
if(this.eventServiceSub){
this.eventServiceSub.unsubscribe();
}
} 
}
事件列表组件.html

<h1 style="color: #76323f">
  {{title}}
</h1>

<h4>
  {{description}}
</h4>
<h2>Coming Soon....</h2>
<app-events-list [upcomingEvents]="upcomingEvents"></app-events-list>
    <virtual-scroll [items]="items" (update)="upcomingEvents = $event"
    (change)="onlistChange($event)">
     <app-upcomingevent *ngFor="let upcomingEvent of upcomingEvents"[upcomingEvent]="upcomingEvent" [eventItemCss]="'event-item'"></app-upcomingevent>
     <div *ngIf="loading" class="loader">Loading.....</div>
    </virtual-scroll>
<md-card [ngClass]="'event-item'">
  <h4 [ngClass]="'event-title'" [ngStyle]="{'color':'purple'}"> {{upcomingEvent.title}}</h4>    
   <md-card-actions>
    <button md-button>LIKE</button>
    <button md-button>SHARE</button>
   </md-card-actions>
</md-card>
...
<app-events-list [items]="upcomingEvents"></app-events-list>

加载。。。。。
事件列表组件.ts

import {Component, OnInit,OnDestroy } from '@angular/core';
import {UpcomingEvent}       from './../../interface/upcomingevent';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

export class HomeComponent implements OnInit, OnDestroy {
  upcomingEvents: Array<UpcomingEvent>;
  title = 'Welcome....';
  description='Events promotions....';
  eventServiceSub: Subscription;

  constructor(private eventService: EventService){
    this.upcomingEvents = [];
  }

  ngOnInit() {
    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{this.upcomingEvents=upcomingEvents.slice(0,25);
    });
  }
  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 
}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 upcomingEvents: Array<UpcomingEvent>;

 items=this.upcomingEvents;
 protected buffer: Array<UpcomingEvent> =[];
 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.buffer.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.buffer=upcomingEvents.slice(this.buffer.length,25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
import { Injectable } from '@angular/core';
import {UpcomingEvent} from './../interface/upcomingevent'
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class EventService {

  constructor(private http: Http) { }

  getEvents(): Observable<UpcomingEvent[]>
  {
    return this.http
       .get(`https://jsonplaceholder.typicode.com/posts`)
       .map(response => response.json() as UpcomingEvent[]);

  }
}
import { Component, Input,OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
@Component({
  selector: 'app-upcomingevent',
  templateUrl: './upcomingevent.component.html',
  styleUrls: ['./upcomingevent.component.css']
})
export class UpcomingeventComponent implements OnInit {

 @Input()
 upcomingEvent: UpcomingEvent;

 @Input()
 eventItemCss: string;

  constructor() { }

  ngOnInit() {
    if (!this.upcomingEvent) {
     this.upcomingEvent=<UpcomingEvent> {}; 
     }

    }

}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 items: Array<UpcomingEvent> = [];

 upcomingEvents: Array<UpcomingEvent>;

 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.items.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.items=upcomingEvents.slice(0, this.items.length + 25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
从'@angular/core'导入{Component,Input,OnDestroy,OnInit};
从“/../../interface/UpcomingEvent”导入{UpcomingEvent};
从“@angular/animations”导入{触发器、状态、样式、转换、动画、关键帧};
从“angular2虚拟卷轴”导入{ChangeEvent};
从“/../services/event.service”导入{EventService};
从'rxjs/Subscription'导入{Subscription};
@组成部分({
选择器:“应用程序事件列表”,
templateUrl:'./events list.component.html',
样式URL:['./events list.component.css'],
动画:[]
})
导出类EventsListComponent实现OnInit、OnDestroy{
@输入()
upcomingEvents:数组;
items=this.upcomingEvents;
受保护的缓冲区:数组=[];
保护加载:布尔;
eventServiceSub:订阅;
构造函数(私有eventService:eventService){
this.upcomingEvents=[];
}
恩戈尼尼特(){
}
恩贡德斯特罗(){
if(this.eventServiceSub){
this.eventServiceSub.unsubscribe();
}
} 
受保护的onlistChange(事件:ChangeEvent){
if(event.end!==this.buffer.length)返回;
这个。加载=真;
this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
this.buffer=upcomingEvents.slice(this.buffer.length,25);
这个。加载=假;
},()=>this.loading=false);
}
}
eventService.ts

import {Component, OnInit,OnDestroy } from '@angular/core';
import {UpcomingEvent}       from './../../interface/upcomingevent';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

export class HomeComponent implements OnInit, OnDestroy {
  upcomingEvents: Array<UpcomingEvent>;
  title = 'Welcome....';
  description='Events promotions....';
  eventServiceSub: Subscription;

  constructor(private eventService: EventService){
    this.upcomingEvents = [];
  }

  ngOnInit() {
    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{this.upcomingEvents=upcomingEvents.slice(0,25);
    });
  }
  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 
}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 upcomingEvents: Array<UpcomingEvent>;

 items=this.upcomingEvents;
 protected buffer: Array<UpcomingEvent> =[];
 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.buffer.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.buffer=upcomingEvents.slice(this.buffer.length,25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
import { Injectable } from '@angular/core';
import {UpcomingEvent} from './../interface/upcomingevent'
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class EventService {

  constructor(private http: Http) { }

  getEvents(): Observable<UpcomingEvent[]>
  {
    return this.http
       .get(`https://jsonplaceholder.typicode.com/posts`)
       .map(response => response.json() as UpcomingEvent[]);

  }
}
import { Component, Input,OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
@Component({
  selector: 'app-upcomingevent',
  templateUrl: './upcomingevent.component.html',
  styleUrls: ['./upcomingevent.component.css']
})
export class UpcomingeventComponent implements OnInit {

 @Input()
 upcomingEvent: UpcomingEvent;

 @Input()
 eventItemCss: string;

  constructor() { }

  ngOnInit() {
    if (!this.upcomingEvent) {
     this.upcomingEvent=<UpcomingEvent> {}; 
     }

    }

}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 items: Array<UpcomingEvent> = [];

 upcomingEvents: Array<UpcomingEvent>;

 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.items.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.items=upcomingEvents.slice(0, this.items.length + 25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
从'@angular/core'导入{Injectable};
从“/../interface/UpcomingEvent”导入{UpcomingEvent}
从'@angular/Http'导入{Http};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/map';
@可注射()
导出类事件服务{
构造函数(私有http:http){}
getEvents():可观察
{
返回此文件。http
.得到(`https://jsonplaceholder.typicode.com/posts`)
.map(response=>response.json()作为UpcomingEvent[]);
}
}
upcomingEvents.html

<h1 style="color: #76323f">
  {{title}}
</h1>

<h4>
  {{description}}
</h4>
<h2>Coming Soon....</h2>
<app-events-list [upcomingEvents]="upcomingEvents"></app-events-list>
    <virtual-scroll [items]="items" (update)="upcomingEvents = $event"
    (change)="onlistChange($event)">
     <app-upcomingevent *ngFor="let upcomingEvent of upcomingEvents"[upcomingEvent]="upcomingEvent" [eventItemCss]="'event-item'"></app-upcomingevent>
     <div *ngIf="loading" class="loader">Loading.....</div>
    </virtual-scroll>
<md-card [ngClass]="'event-item'">
  <h4 [ngClass]="'event-title'" [ngStyle]="{'color':'purple'}"> {{upcomingEvent.title}}</h4>    
   <md-card-actions>
    <button md-button>LIKE</button>
    <button md-button>SHARE</button>
   </md-card-actions>
</md-card>
...
<app-events-list [items]="upcomingEvents"></app-events-list>

{{upcomingEvent.title}
喜欢
分享
upcomingEvents.component.ts

import {Component, OnInit,OnDestroy } from '@angular/core';
import {UpcomingEvent}       from './../../interface/upcomingevent';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

export class HomeComponent implements OnInit, OnDestroy {
  upcomingEvents: Array<UpcomingEvent>;
  title = 'Welcome....';
  description='Events promotions....';
  eventServiceSub: Subscription;

  constructor(private eventService: EventService){
    this.upcomingEvents = [];
  }

  ngOnInit() {
    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{this.upcomingEvents=upcomingEvents.slice(0,25);
    });
  }
  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 
}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 upcomingEvents: Array<UpcomingEvent>;

 items=this.upcomingEvents;
 protected buffer: Array<UpcomingEvent> =[];
 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.buffer.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.buffer=upcomingEvents.slice(this.buffer.length,25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
import { Injectable } from '@angular/core';
import {UpcomingEvent} from './../interface/upcomingevent'
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class EventService {

  constructor(private http: Http) { }

  getEvents(): Observable<UpcomingEvent[]>
  {
    return this.http
       .get(`https://jsonplaceholder.typicode.com/posts`)
       .map(response => response.json() as UpcomingEvent[]);

  }
}
import { Component, Input,OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
@Component({
  selector: 'app-upcomingevent',
  templateUrl: './upcomingevent.component.html',
  styleUrls: ['./upcomingevent.component.css']
})
export class UpcomingeventComponent implements OnInit {

 @Input()
 upcomingEvent: UpcomingEvent;

 @Input()
 eventItemCss: string;

  constructor() { }

  ngOnInit() {
    if (!this.upcomingEvent) {
     this.upcomingEvent=<UpcomingEvent> {}; 
     }

    }

}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 items: Array<UpcomingEvent> = [];

 upcomingEvents: Array<UpcomingEvent>;

 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.items.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.items=upcomingEvents.slice(0, this.items.length + 25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
从'@angular/core'导入{Component,Input,OnInit};
从“/../../interface/UpcomingEvent”导入{UpcomingEvent};
@组成部分({
选择器:“应用程序升级事件”,
templateUrl:'./upcomingevent.component.html',
样式URL:['./upcomingevent.component.css']
})
导出类UpcomingeventComponent实现OnInit{
@输入()
upcomingEvent:upcomingEvent;
@输入()
eventItemCss:string;
构造函数(){}
恩戈尼尼特(){
如果(!this.upcomingEvent){
this.upcomingEvent={};
}
}
}

它假定的工作方式是HomeComponent通过observable从eventService请求数据。然后将数据传递到eventList组件,在该组件上进行迭代,并传递到upcomingEvents组件,以通过HTML呈现。首先会请求25个事件,如果用户滚动到最后,则会从eventService请求另外25个事件…这次是由upcomingEvents组件请求的。我不确定这是最有效的方法,但在任何一种情况下都不起作用。虚拟卷轴似乎对输出没有影响…我非常感谢有人告诉我我做错了什么…谢谢

我想我看到了您代码中的问题。使用虚拟滚动时,需要保留两个数组—一个用于所有加载的数据,另一个用于当前渲染的项目。看起来你把它们弄混了

让我们将所有项数组称为
items
并渲染数组-
upcomingEvents

第一个项目块将从父组件传递,因此:

Home.component.html

<h1 style="color: #76323f">
  {{title}}
</h1>

<h4>
  {{description}}
</h4>
<h2>Coming Soon....</h2>
<app-events-list [upcomingEvents]="upcomingEvents"></app-events-list>
    <virtual-scroll [items]="items" (update)="upcomingEvents = $event"
    (change)="onlistChange($event)">
     <app-upcomingevent *ngFor="let upcomingEvent of upcomingEvents"[upcomingEvent]="upcomingEvent" [eventItemCss]="'event-item'"></app-upcomingevent>
     <div *ngIf="loading" class="loader">Loading.....</div>
    </virtual-scroll>
<md-card [ngClass]="'event-item'">
  <h4 [ngClass]="'event-title'" [ngStyle]="{'color':'purple'}"> {{upcomingEvent.title}}</h4>    
   <md-card-actions>
    <button md-button>LIKE</button>
    <button md-button>SHARE</button>
   </md-card-actions>
</md-card>
...
<app-events-list [items]="upcomingEvents"></app-events-list>
。。。
事件列表组件.html看起来不错

事件列表组件.ts

import {Component, OnInit,OnDestroy } from '@angular/core';
import {UpcomingEvent}       from './../../interface/upcomingevent';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

export class HomeComponent implements OnInit, OnDestroy {
  upcomingEvents: Array<UpcomingEvent>;
  title = 'Welcome....';
  description='Events promotions....';
  eventServiceSub: Subscription;

  constructor(private eventService: EventService){
    this.upcomingEvents = [];
  }

  ngOnInit() {
    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{this.upcomingEvents=upcomingEvents.slice(0,25);
    });
  }
  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 
}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 upcomingEvents: Array<UpcomingEvent>;

 items=this.upcomingEvents;
 protected buffer: Array<UpcomingEvent> =[];
 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.buffer.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.buffer=upcomingEvents.slice(this.buffer.length,25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
import { Injectable } from '@angular/core';
import {UpcomingEvent} from './../interface/upcomingevent'
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class EventService {

  constructor(private http: Http) { }

  getEvents(): Observable<UpcomingEvent[]>
  {
    return this.http
       .get(`https://jsonplaceholder.typicode.com/posts`)
       .map(response => response.json() as UpcomingEvent[]);

  }
}
import { Component, Input,OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
@Component({
  selector: 'app-upcomingevent',
  templateUrl: './upcomingevent.component.html',
  styleUrls: ['./upcomingevent.component.css']
})
export class UpcomingeventComponent implements OnInit {

 @Input()
 upcomingEvent: UpcomingEvent;

 @Input()
 eventItemCss: string;

  constructor() { }

  ngOnInit() {
    if (!this.upcomingEvent) {
     this.upcomingEvent=<UpcomingEvent> {}; 
     }

    }

}
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UpcomingEvent } from './../../interface/upcomingevent';
import { trigger,state,style,transition,animate,keyframes } from '@angular/animations';
import { ChangeEvent } from 'angular2-virtual-scroll';
import {EventService}        from './../../services/event.service';
import {Subscription}        from 'rxjs/Subscription';

@Component({
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css'],
  animations: []
})
export class EventsListComponent implements OnInit, OnDestroy {


 @Input()
 items: Array<UpcomingEvent> = [];

 upcomingEvents: Array<UpcomingEvent>;

 protected loading: boolean;
 eventServiceSub: Subscription;


 constructor(private eventService: EventService) { 
    this.upcomingEvents=[];
 }

  ngOnInit() {
  }

  ngOnDestroy(){
    if (this.eventServiceSub){
      this.eventServiceSub.unsubscribe();
    }
  } 

  protected onlistChange(event: ChangeEvent){
    if (event.end !==this.items.length) return;
    this.loading=true;

    this.eventServiceSub=this.eventService.getEvents().subscribe(upcomingEvents=>{
         this.items=upcomingEvents.slice(0, this.items.length + 25);
         this.loading=false;
      }, ()=> this.loading=false);
   }
 }
从'@angular/core'导入{Component,Input,OnDestroy,OnInit};
从“/../../interface/UpcomingEvent”导入{UpcomingEvent};
从“@angular/animations”导入{触发器、状态、样式、转换、动画、关键帧};
从“angular2虚拟卷轴”导入{ChangeEvent};
从“/../services/event.service”导入{EventService};
从'rxjs/Subscription'导入{Subscription};
@组成部分({
选择器:“应用程序事件列表”,
模板URL:'。/ev