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

Posted

技术标签:

【中文标题】如何在不刷新整个页面的情况下刷新视图中的数据?有角度的【英文标题】:How to refresh data from view without refreshing the whole page? angular 【发布时间】:2017-07-25 10:26:38 【问题描述】:

我对 Angular 4 还很陌生,我正在尝试制作一个可以显示用户日志的网站。我的问题是如何从数据库中获取新数据并将其显示到我的角度页面而不刷新页面。我的朋友告诉我使用 ajax,是否有任何内置的解决方案可以解决我的问题?这是我的服务代码

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>

【问题讨论】:

【参考方案1】:

在理想情况下,服务器端应该设置一个推送通知方法,告诉客户端有新数据可用。

如果这不可用,您可以使用setInterval() 更新您的allItems 变量,该变量保存从服务返回的所有数据。我建议您在您的 component.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 一样吗? 可以详细阅读here 我尝试使用此解决方案,但它所做的只是获取新数据。我可以为实际的 html 页面做点什么来显示新数据并重新加载页面吗? this.allItems = data; 正在将新检索到的数据设置为变量。 Angular 会自动使用 allItems 的新值更新视图。 @Nehal,你能看看这个吗:***.com/questions/65371976/…

以上是关于如何在不刷新整个页面的情况下刷新视图中的数据?有角度的的主要内容,如果未能解决你的问题,请参考以下文章

如何在不刷新整个页面的情况下重新加载组件?

如何在不重新加载整个页面的情况下刷新 div?

如何在不刷新整个页面的情况下让 Grunt/Watch/LiveReload 重新加载 Sass/CSS?

Ajax 功能无法在不刷新页面的情况下正常删除

如何在不刷新页面的情况下从数据库中的textarea添加数据[重复]

是否可以在不刷新整个页面的情况下刷新包含的 Django 模板?