在angular4

时间:2017-05-23 18:59:06

标签: javascript html angular observable vertical-scrolling

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

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

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

事件一览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>

事件一览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

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

<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

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

    }

}

它假设工作的方式是HomeComponent通过observable从eventService请求数据......然后将数据传递给eventList组件,在那里迭代它并传递给comingEvents组件以通过HTML呈现。首先请求25个事件,如果用户滚动到最后,则从eventService请求另外25个事件......这次是来自comingEvents组件。我不确定这是否是最有效的方法,但在任何一种情况下它都不起作用。虚拟滚动似乎对输出没有影响....我真的很感谢有人向我展示我做错了什么....谢谢

1 个答案:

答案 0 :(得分:0)

我认为我的代码中存在问题。使用虚拟滚动时,您需要保留两个数组 - 一个用于所有已加载的数据,另一个用于当前呈现的项目。看起来你有点混淆了。

让我们将all-items-array称为items和render-array - upcomingEvents

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

<强> Home.component.html

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

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

<强>事件一览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);
   }
 }

警告!代码未经过测试,我只是编辑了您的代码。