如何在不刷新整个页面的情况下刷新视图中的数据? Angular

5

我是一个刚接触Angular 4的新手,正在尝试制作一个能够显示用户日志的网站。我的问题是如何从数据库获取新数据并在不刷新页面的情况下将其显示在我的Angular页面上。我的朋友告诉我可以使用ajax,但Angular中是否有任何内置的解决方案可以解决我的问题?以下是我的服务代码:

import { Injectable } from '@angular/core';
import {Http,Headers} from '@angular/http';
import *  as _ from 'underscore';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/toPromise';
import {tokenNotExpired} from 'angular2-jwt';


@Injectable()
export class PagerService {

    authToken:any;
  constructor(private http:Http) { }

  getzip(){
    //gets all the data that matches the users zipcode
        var headers = new Headers();
        this.loadToken();//access token
        headers.append('Authorization',this.authToken);
        headers.append('Content-type','application/json');
        return this.http.get('http://localhost:3000/logs/getByName',{headers:headers})
        .toPromise().then((res) => res.json());
    }


   loadToken(){

        var token = localStorage.getItem('id_token');
        this.authToken = token;
        //this.user = user;
    }

getPager(totalItems: number, currentPage: number = 1, pageSize: number = 10) {
        // calculate total pages
        let totalPages = Math.ceil(totalItems / pageSize);

        let startPage: number, endPage: number;
        if (totalPages <= 10) {
            // less than 10 total pages so show all
            startPage = 1;
            endPage = totalPages;
        } else {
            // more than 10 total pages so calculate start and end pages
            if (currentPage <= 6) {
                startPage = 1;
                endPage = 10;
            } else if (currentPage + 4 >= totalPages) {
                startPage = totalPages - 9;
                endPage = totalPages;
            } else {
                startPage = currentPage - 5;
                endPage = currentPage + 4;
            }
        }

        // calculate start and end item indexes
        let startIndex = (currentPage - 1) * pageSize;
        let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

        // create an array of pages to ng-repeat in the pager control
        let pages = _.range(startPage, endPage + 1);

        // return object with all pager properties required by the view
        return {
            totalItems: totalItems,
            currentPage: currentPage,
            pageSize: pageSize,
            totalPages: totalPages,
            startPage: startPage,
            endPage: endPage,
            startIndex: startIndex,
            endIndex: endIndex,
            pages: pages
        };
    }
}

这是我的组件.ts文件

    import { Component, OnInit } from '@angular/core';
    import {PagerService} from '../../service/pager.service';
    import {Router} from '@angular/router';
    import { Observable } from 'rxjs/Observable';
    import { Http, Headers, RequestOptions, Response } from '@angular/http';
    import *  as _ from 'underscore';


    @Component({
      selector: 'app-messages',
      templateUrl: './messages.component.html',
      styleUrls: ['./messages.component.css']
    })
    export class MessagesComponent implements OnInit {



      constructor(private pagerService:PagerService,
                  private router:Router,
                  private http:Http
                ) { }

        doc:any[];
        // array of all items to be paged
        private allItems: any[];

        // pager object
        pager: any = {};

        // paged items
        pagedItems: any[];

        row:any;

      ngOnInit() {
         this.pagerService.getzip().then(data =>{
         this.allItems = data;this.setPage(1);
         console.log(JSON.stringify(this.allItems.length),"MESSAGES")
    },err=>{console.log(err); return false;});
      }
    setPage(page: number) {
            if (page < 1 || page > this.pager.totalPages) {
                return;
            }
            // get pager object from service
            this.pager = this.pagerService.getPager(this.allItems.length, page);
            // get current page of items
            this.pagedItems = this.allItems.slice(this.pager.startIndex, this.pager.endIndex + 1);
            console.log(this.pager.startIndex,this.pager.endIndex)

          }



    }

这是我的观点:
<div *ngIf="allItems && allItems.length <= 0" class="alert alert-dismissible alert-success">
  <button type="button" class="close" data-dismiss="alert">&times;</button>
  <strong>Well done!</strong> There no currently <a href="#" class="alert-link">messages to display</a>.
</div>

<div *ngIf="allItems && allItems.length > 0">
<table class="table table-striped table-hover ">
  <thead>
    <tr>
      <th></th>
      <th>Plate Number</th>
      <th>Date</th>
      <th>Time</th>
      <th>Location</th>
    </tr>
  </thead>
  <tbody >
    <tr *ngFor ="let x of pagedItems;let i = index">
      <td>{{i+(pager.startIndex+1)}}</td>
      <td>{{x.platenumber}}</td>
      <td>{{x.date.month}}-{{x.date.dayN}}-{{x.date.year}}</td>
      <td>{{x.time}}</td>
      <td>{{x.location.street}}</td>
    </tr>
  </tbody>
</table>
</div>

<div class = "text-center">
<!-- pager -->
            <ul *ngIf="pager.pages && pager.pages.length" class="pagination">
                <li [ngClass]="{disabled:pager.currentPage === 1}">
                    <a (click)="setPage(1)">First</a>
                </li>
                <li [ngClass]="{disabled:pager.currentPage === 1}">
                    <a (click)="setPage(pager.currentPage - 1)">Previous</a>
                </li>
                <li *ngFor="let page of pager.pages" [ngClass]="{active:pager.currentPage === page}">
                    <a (click)="setPage(page)">{{page}}</a>
                </li>
                <li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
                    <a (click)="setPage(pager.currentPage + 1)">Next</a>
                </li>
                <li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
                    <a (click)="setPage(pager.totalPages)">Last</a>
                </li>
            </ul>
</div>
2个回答

6
在理想情况下,服务器端应设置推送通知方法,告知客户端有新数据可用。
如果没有这个方法,你可以使用setInterval()来更新allItems变量,该变量保存了从服务返回的所有数据。我建议你在组件.ts中进行以下调整:
dataRefresher: any;

ngOnInit() {
  this.getData(true);
  this.refreshData();     
}

getData(setPageFlag){
  this.pagerService.getzip().then(data =>{
    this.allItems = data;
    if(setPageFlag){
      this.setPage(1);
    }
    console.log(JSON.stringify(this.allItems.length),"MESSAGES")
  },
  err => { console.log(err); return false;});
}

refreshData(){
  this.dataRefresher =
    setInterval(() => {
      this.getData(false);
      //Passing the false flag would prevent page reset to 1 and hinder user interaction
    }, 30000);  
}

刷新时间设置为30秒,您可以根据需要更改它 :)

您还可以添加一个函数来清除间隔,并在ngOnDestroy上调用它:

cancelPageRefresh(){
    if(this.dataRefresher){
        clearInterval(this.dataRefresher);
    }    
}

ngOnDestroy(){
  this.cancelPageRefresh();
}

如果你使用了 OnDestroy,不要忘记import它并将其添加在类的implementation 中。

非常抱歉,我可以问一下什么是推送通知方法吗?这和使用Socket.io一样吗? - Ralph Mungcal
你可以在这里详细阅读:https://dev59.com/gFsX5IYBdhLWcg3wjv-f - Nehal
我尝试使用这个解决方案,但它只是获取新数据。我能做些什么来让实际的HTML页面显示新数据而不需要重新加载页面吗? - Ralph Mungcal
1
this.allItems = data; 将新获取的数据设置到变量中。Angular 会自动使用 allItems 的新值更新视图。 - Nehal
@Nehal,你能否看一下这个问题:https://stackoverflow.com/questions/65371976/how-to-reload-a-component-in-angular-without-reloading-the-whole-page - Tanzeel
@Nehal,我被卡了好几天了。我需要你的帮助。 - Tanzeel

1

刷新数据而不重新加载整个HTML页面的一种方法是在Angular的生命周期钩子中重新分配数据源。在下面的代码片段中,为了显示最新的数据,我使用了AfterViewChecked钩子。 component.ts

ngAfterViewChecked(): void {
this.lstorage = JSON.parse(localStorage.getItem('employee')!);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接