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); this.$emit('row-edit-cancel', event);
}, },
createLazyLoadEvent(event) { createLazyLoadEvent(event) {
let filterMatchModes;
if (this.hasFilters) {
filterMatchModes = {};
this.columns.forEach(col => {
if (col.field) {
filterMatchModes[col.field] = col.filterMatchMode;
}
});
}
return { return {
originalEvent: event, originalEvent: event,
first: this.d_first, first: this.d_first,
@ -1561,8 +1551,7 @@ export default {
sortField: this.d_sortField, sortField: this.d_sortField,
sortOrder: this.d_sortOrder, sortOrder: this.d_sortOrder,
multiSortMeta: this.d_multiSortMeta, multiSortMeta: this.d_multiSortMeta,
filters: this.filters, filters: this.d_filters
filterMatchModes: filterMatchModes
}; };
}, },
hasGlobalFilter() { hasGlobalFilter() {
@ -1578,6 +1567,10 @@ export default {
this.d_first = 0; this.d_first = 0;
this.$emit('update:first', this.d_first); this.$emit('update:first', this.d_first);
this.$emit('update:filters', this.d_filters); this.$emit('update:filters', this.d_filters);
if (this.lazy) {
this.$emit('filter', this.createLazyLoadEvent());
}
}, },
cloneFilters() { cloneFilters() {
let cloned = {}; 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> 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> <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. <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 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>
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 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 <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 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 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>
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>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> <p>Visit the <router-link to="/datatable/lazy">lazy loading</router-link> demo for an example with a remote datasource.</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>
<h5>Row Expansion</h5> <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> <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.sortOrder: Sort order as integer <br />
event.multiSortMeta: MultiSort metadata <br /> event.multiSortMeta: MultiSort metadata <br />
event.filters: Collection of active filters <br /> event.filters: Collection of active filters <br />
event.filteredValue: Filtered collection <br /> event.filteredValue: Filtered collection (non-lazy only)<br />
event.filterMatchModes: Match modes per field
</td> </td>
<td>Event to emit after filtering, not triggered in lazy mode.</td> <td>Event to emit after filtering, not triggered in lazy mode.</td>
</tr> </tr>

View File

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