Fixed #1105 - Filter Event for Lazy Loading

pull/1196/head^2
Cagatay Civici 2021-05-14 18:50:45 +03:00
parent cfa4b06c03
commit 5319c59d01
3 changed files with 14 additions and 92 deletions

View File

@ -1544,16 +1544,6 @@ export default {
this.$emit('row-edit-cancel', event);
},
createLazyLoadEvent(event) {
let filterMatchModes;
if (this.hasFilters) {
filterMatchModes = {};
this.columns.forEach(col => {
if (col.field) {
filterMatchModes[col.field] = col.filterMatchMode;
}
});
}
return {
originalEvent: event,
first: this.d_first,
@ -1561,8 +1551,7 @@ export default {
sortField: this.d_sortField,
sortOrder: this.d_sortOrder,
multiSortMeta: this.d_multiSortMeta,
filters: this.filters,
filterMatchModes: filterMatchModes
filters: this.d_filters
};
},
hasGlobalFilter() {
@ -1578,6 +1567,10 @@ export default {
this.d_first = 0;
this.$emit('update:first', this.d_first);
this.$emit('update:filters', this.d_filters);
if (this.lazy) {
this.$emit('filter', this.createLazyLoadEvent());
}
},
cloneFilters() {
let cloned = {};

View File

@ -1030,68 +1030,13 @@ matchModes: [
data are still displayed. No additional configuration is required to enable this feature. View the <router-link to="/datatable/rowgroup">Row Grouğ</router-link> demo for an example.</p>
<h5>Lazy Loading</h5>
<p>Lazy mode is handy to deal with large datasets, instead of loading the entire data, small chunks of data is loaded by invoking corresponding callbacks such as paging and sorting. Sample belows imitates lazy paging by using an in memory list.
It is also important to assign the logical number of rows to totalRecords by doing a projection query for paginator configuration so that paginator displays the UI
assuming there are actually records of totalRecords size although in reality they aren't as in lazy mode, only the records that are displayed on the current page exist.</p>
<p>Lazy mode is handy to deal with large datasets, instead of loading the entire data, small chunks of data is loaded by invoking corresponding callbacks such as paging and sorting.
It is also important to assign the logical number of rows to totalRecords by doing a projection query for paginator configuration so that paginator displays the UI accordingly.</p>
<p>Lazy loading is implemented by handling pagination and sorting using <i>page</i> and <i>sort</i> events by making a remote query using the information
passed to the events such as first offset, number of rows and sort field for ordering. Filtering is handled differently as filter elements are defined using templates. <i>filter</i> event is not triggered in
lazy mode instead use the event you prefer on your form elements such as input, change, blur to make a remote call by passing the filters property to update the displayed data. Note that,
in lazy filtering, totalRecords should also be updated to align the data with the paginator.</p>
<p>Lazy loading is implemented by handling <i>page</i>, <i>sort</i>, <i>filter</i> events by making a remote query using the information
passed to these events such as first offset, number of rows, sort field for ordering and filters. Note that, in lazy filtering totalRecords should also be updated to align the data with the paginator.</p>
<p>Here is a sample paging implementation with in memory data, a more enhanced example with a backend is being worked on and will be available at a github repository.</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" :lazy="true" :paginator="true" :rows="10"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)"&gt;
&lt;Column field="vin" header="Vin"&gt;&lt;/Column&gt;
&lt;Column field="year" header="Year"&gt;&lt;/Column&gt;
&lt;Column field="brand" header="Brand"&gt;&lt;/Column&gt;
&lt;Column field="color" header="Color"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
</template>
</code></pre>
<pre v-code.script><code>
import CarService from '../../service/CarService';
export default {
data() {
return {
loading: false,
totalRecords: 0,
cars: null
}
},
datasource: null,
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.loading = true;
setTimeout(() => {
this.carService.getCarsLarge().then(data => {
this.datasource = data;
this.totalRecords = data.length,
this.cars = this.datasource.slice(0, 10);
this.loading = false;
});
}, 1000);
},
methods: {
onPage(event) {
this.loading = true;
setTimeout(() => {
this.cars = this.datasource.slice(event.first, event.first + event.rows);
this.loading = false;
}, 1000);
}
}
}
</code></pre>
<p>Visit the <router-link to="/datatable/lazy">lazy loading</router-link> demo for an example with a remote datasource.</p>
<h5>Row Expansion</h5>
<p>Rows can be expanded to display additional content using the <i>expandedRows</i> property with the v-model directive accompanied by a template named "expansion". <i>row-expand</i> and <i>row-collapse</i> are optional callbacks that are invoked when a row is expanded or toggled.</p>
@ -2285,8 +2230,7 @@ export default {
event.sortOrder: Sort order as integer <br />
event.multiSortMeta: MultiSort metadata <br />
event.filters: Collection of active filters <br />
event.filteredValue: Filtered collection <br />
event.filterMatchModes: Match modes per field
event.filteredValue: Filtered collection (non-lazy only)<br />
</td>
<td>Event to emit after filtering, not triggered in lazy mode.</td>
</tr>

View File

@ -14,7 +14,7 @@
<div class="content-section implementation">
<div class="card">
<DataTable :value="customers" :lazy="true" :paginator="true" :rows="10" v-model:filters="filters" ref="dt"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)" @sort="onSort($event)" filterDisplay="row"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)" @sort="onSort($event)" @filter="onFilter($event)" filterDisplay="row"
:globalFilterFields="['name','country.name', 'company', 'representative.name']" responsiveLayout="scroll" >
<Column field="name" header="Name" filterMatchMode="startsWith" ref="name" :sortable="true">
<template #filter="{filterModel,filterCallback}">
@ -48,11 +48,6 @@
import CustomerService from '../../service/CustomerService';
export default {
watch: {
filters() {
this.onFilter();
}
},
data() {
return {
loading: false,
@ -78,7 +73,7 @@ export default {
<template>
<div>
<DataTable :value="customers" :lazy="true" :paginator="true" :rows="10" v-model:filters="filters" ref="dt"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)" @sort="onSort($event)" filterDisplay="row"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)" @sort="onSort($event)" @filter="onFilter($event)" filterDisplay="row"
:globalFilterFields="['name','country.name', 'company', 'representative.name']" responsiveLayout="scroll">
<Column field="name" header="Name" filterMatchMode="startsWith" ref="name" :sortable="true">
<template #filter="{filterModel,filterCallback}">
@ -108,11 +103,6 @@ export default {
import CustomerService from './service/CustomerService';
export default {
watch: {
filters() {
this.onFilter();
}
},
data() {
return {
loading: false,
@ -189,7 +179,7 @@ export default {
<template>
<div>
<DataTable :value="customers" :lazy="true" :paginator="true" :rows="10" v-model:filters="filters" ref="dt"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)" @sort="onSort($event)" filterDisplay="row"
:totalRecords="totalRecords" :loading="loading" @page="onPage($event)" @sort="onSort($event)" @filter="onFilter($event)" filterDisplay="row"
:globalFilterFields="['name','country.name', 'company', 'representative.name']" responsiveLayout="scroll">
<Column field="name" header="Name" filterMatchMode="startsWith" ref="name" :sortable="true">
<template #filter="{filterModel,filterCallback}">
@ -220,11 +210,6 @@ import { ref, onMounted } from 'vue';
import CustomerService from './service/CustomerService';
export default {
watch: {
filters() {
this.onFilter();
}
},
setup() {
onMounted(() => {
loading.value = true;