如何在不刷新整个页面的情况下刷新视图中的数据?有角度的
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">×</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/…以上是关于如何在不刷新整个页面的情况下刷新视图中的数据?有角度的的主要内容,如果未能解决你的问题,请参考以下文章
如何在不刷新整个页面的情况下让 Grunt/Watch/LiveReload 重新加载 Sass/CSS?