Angular 实现分段式加载,滚动刷新数据

如何在angular中实现数据的分段渐进式加载,滚动到页面底部时刷新数据,在app端我们可以用ionic来实现下拉刷新,这里讨论pc端的滚动刷新,我用到了primeNG,primeNG是一个专门为angular设计的UI组件库(链接:https://www.primefaces.org/primeng/#/)。

以下具体讨论实现的步骤:

1.在angular应用中安装该组件

   npm install primeng --save    (在terminal中运行这个命令)

2.在应用的根模块中导入要用到的primeng模块

3.如果需要用到primeNG的css样式也可以自己在angular-cli.json文件中配置

4.环境搭建好了,现在就可以开始写代码了,下面以我写的demo为例:

  创建一个scroll-refresh文件

 

  html页面:

<p-dataScroller [value]="activityLog" [rows]="5" [inline]="true" [lazy]="true" (onLazyLoad)="loadData($event)" scrollHeight="500px">
  <p-header>
      Scroll Down to  Load More
  </p-header>
  <ng-template let-activityLog pTemplate="item">
      <div class="ui-grid ui-grid-responsive ui-fluid" style="font-size:16px;padding:20px;border-bottom:1px solid #D5D5D5">
          <div class="ui-grid-row">
              <div class="ui-grid-col-3" style="text-align:center">
                <img class="responsive" width="120rem" height="130rem" src="assets/showcase/images/1.jpg">
              </div>
              <div class="ui-grid-col-9">
                  <div class="ui-grid ui-grid-responsive ui-fluid">
                      <div class="ui-grid-row">
                          <div class="ui-grid-col-2">编号: </div>
                          <div class="ui-grid-col-10">{{activityLog.ActivityLogId}}</div>
                      </div>
                      <div class="ui-grid-row">
                          <div class="ui-grid-col-2">内容: </div>
                          <div class="ui-grid-col-10">{{activityLog.Description}}</div>
                      </div>
                      <div class="ui-grid-row">
                          <div class="ui-grid-col-2">设备: </div>
                          <div class="ui-grid-col-10">{{activityLog.DeviceName}}</div>
                      </div>
                      <div class="ui-grid-row">
                          <div class="ui-grid-col-2">时间: </div>
                          <div class="ui-grid-col-10">{{activityLog.Time}}</div>
                      </div>
                  </div>
              </div>
          </div>
      </div>
  </ng-template>
</p-dataScroller>

<p-dialog header="activityLog Details" [visible]="displayDialog"  showEffect="fade" [modal]="true" width="225" (onAfterHide)="onDialogHide()">
  <div class="ui-grid ui-grid-responsive ui-fluid" *ngIf="selectedActivityLog" style="font-size:16px;text-align:center;padding:20px">
      <div class="ui-grid-row">
          <div class="ui-grid-col-12" style="text-align:center"><img src="assets/showcase/images/1.jpg"></div>
      </div>
      <div class="ui-grid-row">
          <div class="ui-grid-col-4">编号: </div>
          <div class="ui-grid-col-8">{{selectedActivityLog.ActivityLogId}}</div>
      </div>
      <div class="ui-grid-row">
          <div class="ui-grid-col-4">内容: </div>
          <div class="ui-grid-col-8">{{selectedActivityLog.Description}}</div>
      </div>
      <div class="ui-grid-row">
          <div class="ui-grid-col-4">设备: </div>
          <div class="ui-grid-col-8">{{selectedActivityLog.DeviceName}}</div>
      </div>
      <div class="ui-grid-row">
          <div class="ui-grid-col-4">时间: </div>
          <div class="ui-grid-col-8">{{selectedActivityLog.Time}}</div>
      </div>
  </div>
</p-dialog> 

 

component部分:

import { Component, OnInit, Injectable } from '@angular/core';
import { Http, Response} from '@angular/http';
import { DataScrollerModule} from 'primeng/primeng';

import { ScrollService } from './scroll.service';
import { ActivityLog } from './scroll.model';

@Component({
  selector: 'app-scroll-refresh',
  templateUrl: './scroll-refresh.component.html',
  styleUrls: ['./scroll-refresh.component.css']
})
export class ScrollRefreshComponent implements OnInit {
  activityLog: ActivityLog[];
  selectedActivityLog: ActivityLog;
  displayDialog: boolean;

  constructor(private personService: ScrollService) { }

  ngOnInit() {
    this.personService.getActivities(0, 5).then(person => {
      this.activityLog = person;
    });
  }

  selectPerson(person: ActivityLog) {
    this.selectedActivityLog = person;
    this.displayDialog = true;
  }

  onDialogHide() {
    this.selectedActivityLog = null;
  }

  loadData(event) {
    console.log('==== lazy load ====');
    event.first += 5;
    event.rows = 5;
      if (event.first < 50) {
         console.log(event.first);
          return this.personService.getActivities(event.first, event.rows).then(person => {
                    console.log(person);
                    person.forEach((val) => {
                      this.activityLog.push(val);
                    });
                 });
      } else {
        event.first = 0;
        console.log(event.first);
        return;
      }
  }
}

 

service部分:

import { Injectable } from '@angular/core';
import {Http, Response } from '@angular/http';

import { ActivityLog } from './scroll.model';

import 'rxjs/add/operator/toPromise';


@Injectable()
export class ScrollService {

  constructor(private http: Http) { }

  getActivities(start: number, end: number) {
    return this.http.get('http://localhost:52513/api/activitylogs?start=' + start + '&end=' + end)
                .toPromise()
                .then(res => {
                  return res.json();
                })
                .then(data => {
                   return  data;
                });
    }
}

 

model部分:

export class ActivityLog {
    ActivityLogId: string;
    PatientId: string;
    Therapist: string;
    DeviceName: string;
    Description: string;
    ActivityId: string;
    Time: Date;
    Seconds: number;

    public constructor(
        fields?: {
            ActivityLogId: string;
            PatientId: string;
            Therapist: string;
            DeviceName: string;
            Description: string;
            ActivityId: string;
            Time: Date;
            Seconds: number
        }) {
            if (fields) Object.assign(this, fields);
        }
}

 

app.module部分:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { CommonModule, LocationStrategy, HashLocationStrategy} from '@angular/common';
import { BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule} from '@angular/forms';

import { HttpModule} from '@angular/http';

// primeNG module
import { ScrollService } from './scroll-refresh/scroll.service';
import { MenuItem, AccordionModule, CalendarModule, TabViewModule, CodeHighlighterModule } from 'primeng/primeng';
import { DataScrollerModule} from 'primeng/primeng';
import { DataTableModule} from 'primeng/primeng';
import { DialogModule} from 'primeng/primeng';

// custom primeNG component by myself
import { AppComponent } from './app.component';
import { ScrollRefreshComponent } from './scroll-refresh/scroll-refresh.component';


@NgModule({
  declarations: [
    AppComponent,
    ScrollRefreshComponent,
  ],
  imports: [
    BrowserModule,
    AccordionModule,
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    CalendarModule,
    TabViewModule,
    CodeHighlighterModule,
    DataScrollerModule,
    DataTableModule,
    DialogModule,
    HttpModule,
  ],
  providers: [
    ScrollService,
    { provide: LocationStrategy, useClass: HashLocationStrategy }
  ],
  bootstrap: [ScrollRefreshComponent]
})
export class AppModule { }

 

注: 在app.module文件中我导入了primeNG的很多模块,因为在其他文件中我有用到这些模块,但是如果你只是实现滚动刷新的话,导入对应的模块即可。

 

angular-cli.json文件:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "name": "new-date"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "styles.css",
        "../node_modules/primeng/resources/themes/omega/theme.css",
        "../node_modules/primeng/resources/primeng.min.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "lint": [
    {
      "project": "src/tsconfig.app.json",
      "exclude": "**/node_modules/**"
    },
    {
      "project": "src/tsconfig.spec.json",
      "exclude": "**/node_modules/**"
    },
    {
      "project": "e2e/tsconfig.e2e.json",
      "exclude": "**/node_modules/**"
    }
  ],
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "component": {}
  }
}

 

需要注意的是,实现分段式加载的关键是每次刷新都只加载一部分数据,即只向数据库中拿取一部分数据而不是一次性全部获取,所以在这方面,必须在后端也要进行配置,前端每次刷新时向后端传递2个参数:start和end,start表示从哪条数据开始获取,end表示一次获取多少条数据,类似于数据的分页展示。

 

另外,这个demo是一个基于angular-cli实现的用webpack打包的angular应用,一切配置都是在这个前提下完成的,但是如果你的angular应用是基于system.js用gulp打包实现的,那么你的配置方式与我的demo是不相同的。即,在用命令行安装该组件后,还必须在system.js文件中手动进行配置依赖,这里就不多说了,可以参考primeNG官网的例子。

posted @ 2017-11-24 11:08  Mia_米  阅读(3276)  评论(0编辑  收藏  举报