简体   繁体   English

在angular4中实现可观察到的angular2-virtual-scroll

[英]implement angular2-virtual-scroll with observable in angular4

I am trying to implement angular2-virtual-scroll in an angular4 project. 我正在尝试在angular4项目中实现angular2-virtual-scroll。 Firstly, can anyone confirm if I would have a problem implementing it in NG4. 首先,任何人都可以确认我在NG4中实现它是否会遇到问题。 I don't think I should and I haven't seen any notices to the contrary. 我不认为我应该这样做,也没有看到任何相反的通知。 Secondly I am using an observable instead of a promise shown in the NPM angular2-virtual-scroll docs. 其次,我使用的是可观察的,而不是NPM angular2-virtual-scroll文档中显示的承诺。 However, when I applied the virtual-scroll tag there is no change in my output...no scroll bar ..the data from the observable is displayed but no scrolling. 但是,当我应用virtual-scroll标记时,我的输出没有任何变化...没有滚动条..显示了来自可观察到的数据,但没有滚动。 The following are the relevant code segments: 以下是相关的代码段:

Home.component.html Home.component.html

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

<h4>
  {{description}}
</h4>
<h2>Coming Soon....</h2>
<app-events-list [upcomingEvents]="upcomingEvents"></app-events-list>

home.component.ts 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();
    }
  } 
}

event-list-component.html 事件列表component.html

    <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>

event-list-component.ts 事件列表component.ts

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);
   }
 }

eventService.ts eventService.ts

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[]);

  }
}

upcomingEvents.html upcomingEvents.html

<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>

upcomingEvents.component.ts upcomingEvents.component.ts

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> {}; 
     }

    }

}

The way it suppose to work is that the HomeComponent request data from the eventService via an observable..the data is then passed to the eventList component where it is iterated on and pass to the upcomingEvents component to present via HTML. 它假定工作的方式是HomeComponent经由可观察对象从eventService请求数据。然后将数据传递到eventList组件,在其上对其进行迭代,并传递给即将发生的Events组件以通过HTML呈现。 25 events are requested at first and if the user scroll to the end another 25 is requested from the eventService...this time by the upcomingEvents component. 首先请求25个事件,如果用户滚动到末尾,则从eventService请求另外25个事件...这一次即将到来的Events组件。 I am not sure this is the most efficient way to do it but in either case it doesn't work. 我不确定这是最有效的方法,但无论哪种情况都行不通。 The virtual-scroll seems to have no effect on the output....I would really appreciate someone showing me what I am doing wrong....Thanks 虚拟滚动似乎对输出没有影响。...我真的很感谢有人向我展示我在做错什么。...谢谢

I think I see a problem in your code. 我想我在您的代码中看到了一个问题。 When using virtual-scroll you need to keep two arrays - one for all loaded data, and one for currently rendered items. 使用虚拟滚动时,您需要保留两个数组-一个用于所有加载的数据,一个用于当前渲染的项目。 Looks like you kinda mixed them up. 看起来您有点混了。

Let's call all-items-array as items and render-array - upcomingEvents 让我们将all-items-array称为items和render- upcomingEvents

First chunk of items will be passed from the parent component, hence: 第一部分项目将从父组件传递,因此:

Home.component.html Home.component.html

...
<app-events-list [items]="upcomingEvents"></app-events-list>

event-list-component.html looks good event-list-component.html看起来不错

event-list-component.ts 事件列表component.ts

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);
   }
 }

warning! 警告! code not tested, I simply edited your code. 代码未经测试,我只是编辑了您的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM