我正在使用PouchDB作为数据库,我已经在我的项目中实现了无限滚动。对于第一次加载,将只显示40个文档,对于下一个滚动,它将加载40个文档。我的数据库中的总文档大约是3000个文档。我做无限滚动时没有问题,但是我通过使用无限滚动在过滤数据中遇到问题。我可以搜索已经显示/查看的数据但我无法搜索未查看的数据。它只能过滤已加载的数据。以下是我的代码。
providers.ts
constructor(public http: Http) {
this.db = new PouchDB('location');
console.log('Hello User Provider',this.db);
this.remote = 'http://data/location';
let options = {
live: true,
retry: true
};
this.db.sync(this.remote, options)
.on('change', function(change){
console.log('Users provider change!', change);
})
.on('paused', function(info){
console.log('Users provider paused!', info);
})
.on('active', function(info){
console.log('Users provider active!', info);
})
.on('error', function(err){
console.log('users provider error!', err)
});
}
getUsers(skip,limit){
var total;
return new Promise(resolve => {
this.db.info().then(function (info) {
total = info.doc_count;
})
this.db.allDocs({
include_docs: true,
descending:true,
limit: limit,
skip:skip
})
.then((result) => {
this.data = [];
result.rows.map((row) => {
if(row.doc._id.substring(0,8) !== '_design/'){
this.data.push(row.doc);
}
})
resolve(this.data);
this.db.changes({live: true, since: 'now', include_docs: true})
.on('change', (change) => {
this.handleChange(change);
})
})
.catch((error) => {
console.log('Error when getUsers!', error);
})
})
}
home.html
<ion-content class="sample-modal-page">
<ion-searchbar (ionInput)="getItems($event)">
</ion-searchbar>
<ion-item *ngFor = "let user of users (click)="dismiss(user.Description)">
<h3>{{user.Description}}</h3>
<h4>{{user.code}}</h4>
<h4>{{user.branch}}</h4>
</ion-item>
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content
loadingSpinner="bubbles"
loadingText="Loading more data...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
home.ts
users: any = [];
staff: any = [];
searchQuery: string = '';
skip : any = 0;
limit : any = 40;
constructor(public user: User,public loadingCtrl: LoadingController, public viewCtrl: ViewController, public navCtrl: NavController, public navParams: NavParams)
{
let loadingPopup = this.loadingCtrl.create({
content: 'Loading data...'
});
loadingPopup.present();
//get data from user provider
this.user.getUsers(this.skip,this.limit).then(data => {
this.staff = data;
this.initializeItems();
loadingPopup.dismiss();
});
}
initializeItems() {
this.users = this.staff;
}
getItems(ev) {
this.initializeItems();
var val = ev.target.value;
if (val && val.trim() != '') {
this.users = this.users.filter((user) => {
return (user.Description.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
doInfinite(infiniteScroll){
setTimeout(() => {
this.skip = this.skip + this.limit;
this.user.getUsers(this.skip,this.limit).then((data) => {
for (var i = 0; i < this.limit; i++) {
this.users.push(data[i]);
console.log('Apa ini sebenarnya',this.users);
}
});
console.log('Sync end');
infiniteScroll.complete();
},250);
}
答案 0 :(得分:0)
从您的代码中,您通过发送额外参数来调用查询,该参数是skip和limit。这意味着每个查询只能获得40个数据。
如果要在客户端进行过滤(例如数据表),则需要获取所有数据,而不是在客户端进行操作(过滤,分页)
如果您想坚持自己的方式(发送限制和跳过参数查询功能),您也必须发送过滤器,然后重置限制并跳过参数为0
答案 1 :(得分:0)
最近我遇到了同样的问题,我将从一开始就说明解决方案。
离子2和3具有相同的过程。
1。无限滚动
使用Ionic文档呈现列表非常简单: https://ionicframework.com/docs/v3/api/components/infinite-scroll/InfiniteScroll/
2。搜索栏
同样,请按照Ionic文档配置搜索栏: https://ionicframework.com/docs/v3/api/components/searchbar/Searchbar/
3。管道
最好使用管道过滤元素,您将能够在模板,控制器和模板中同时使用它,并将其在其他组件中重复使用。
对于不需要无限滚动的小列表,我将其直接放在模板中:
<ion-list>
<button *ngFor="let item of items | search : searchbarValue:searchbarFilters">
对于控制器中较长的情况:
let filteredOptions = new SearchPipe().transform(this.items, this.searchbarValue, this.searchbarFilters);
我的真实案例
在我的情况下,this.items
包含2.000个值,因此我无法渲染它们,因此我将使用无限滚动仅渲染已过滤的元素。
我粘贴自己的代码,向您展示它们的外观。
template.html
<ion-searchbar
[placeholder]="searchbarPlaceholder"
(ionInput)="onSearch($event)"
[(ngModel)]="searchbarValue">
</ion-searchbar>
<!-- List filtered elements -->
<ion-list>
<button *ngFor="let item of filteredItems">
controller.ts
dynamicOffset: number = 0;
dynamicLimit: number = 30;
offset: number = 0;
limit: number = 30;
/**
* This function is called when some new value is placed in the searchbar.
* I have two arrays:
* - Original list with 2.000 values (this.items)
* - Filtered list empty (this.filteredItems)
*/
onSearch(): void {
// on every search I reset my filtered list
this.filteredItems.length = 0;
// I call the pipe passing by parameter the ORIGINAL list of items,
// the searchbarValue and the properties to look them for.
// I receive the filtered items.
let filteredItems = new SearchPipe().transform(this.items, this.searchbarValue, this.searchbarFilters);
// I reset the limits of the infinite scroll because I will be filtering in a new list
this.dynamicOffset = this.offset;
this.dynamicLimit = this.limit;
this.loadItems(filteredItems); }
/**
* Load items.
*/
loadItems(items: any = []): void {
let item;
while (this.dynamicOffset < this.dynamicLimit) {
item = items[this.dynamicOffset];
if (!item) break;
this.filteredItems.push(item);
this.dynamicOffset++;
}
this.dynamicLimit = this.dynamicLimit + this.limit;
}
无论如何,这是一个解决问题的方法。还有更多选择,但就我而言,此代码解决了我的后顾之忧。