Ticket T604169
Visible to All Users

DataGrid - DataSource doesn't display filtered values after refresh

created 7 years ago (modified 7 years ago)

I've got a component that displays 3 DxDataGrid. Each grid has its own distinct custom Rest datasource.
By the first grid, I have a on/off switch that apply a filter on the first grid.
When the switch is clicked, the datasource gets reloaded and the grid is expected to be refreshed.
Instead of displaying the new filtered values of the first grid, all the the 3 grids gets refreshed (each of their data source being queried again !).

I put some traces and this is what actually happens :

  1. I click on the switch, on ValueChanged is called and the following code is executed:
JavaScript
switch_onValueChanged(event) { this.showArchive = event.value; this.clientDataSource.load( { "filter": ["archive", "=", (this.showArchive ? 1 : 0)] } ); this.clientGrid.instance.refresh(); }
  1. As a result the data source fetches the correct data from the server, the data is delivered to the browser
  2. It should stop here but it continues and refetch all data of the 3 grids, like if I had click refresh on the browser refresh url button. I do not understand what happens.

If I comment the line

JavaScript
this.clientGrid.instance.refresh();

the filtered data is still fetched from the server, brought back to the browser, but is not displayed in the grid: the grid is not refreshed.

Hence my question: what is the best approach to refresh a data grid on interactive external filtering ?

Thank you.

[EDIT]
I see now why other data sources are also refreshed: they are indeed linked by look up. Still, I do not understand why once loaded with a filter (clientDataSource.load (… ) ),   it is loaded again after this.
Would it be possible to add a callback to the load call and do the refresh afterwards ?

[EDIT2]
I tried the following :

JavaScript
this.clientGrid.instance.filter( ["archive", "=", (this.showArchive ? 1 : 0)] );

But it only empties the grid : the grid is  filtered but I intend to filter the data from the server via the data source

Here is the client.component.html file :

HTML
<dx-data-grid #clientGrid id="clientGrid" [dataSource]="clientDataSource" [hoverStateEnabled]="true" keyExpr="id" (onEditorPreparing)="grid_onEditorPreparing($event)" (onSelectionChanged)="client_grid_onSelectionChanged($event)" > <dxo-selection mode="single"></dxo-selection> <dxo-search-panel [visible]="true" [width]="240" placeholder="Chercher..."></dxo-search-panel> <dxo-paging [enabled]="true"></dxo-paging> <dxo-editing mode="popup" [allowAdding]="true" [allowDeleting]="true" [allowUpdating]="true"> <dxo-popup [fullScreen]="true" title="Détails Client" [showTitle]="true" [width]="1000" [height]="800"> <dxo-form [colCount]="2" [labelLocation]="'left'"> <dxi-item itemType="group" caption="Logo" [colSpan]="2"> <dxi-item dataField="logo"></dxi-item> </dxi-item> <dxi-item itemType="group" caption="Identité"> <dxi-item dataField="nom"></dxi-item> <dxi-item editorType="dxTextArea" [editorOptions]="{ height: 90 }" dataField="activite"></dxi-item> <dxi-item dataField="adresse"></dxi-item> <dxi-item dataField="ville"></dxi-item> <dxi-item dataField="codepostal"></dxi-item> <dxi-item dataField="archive"></dxi-item> </dxi-item> <dxi-item itemType="group" caption="Contact"> <dxi-item dataField="referentPrincipal"></dxi-item> <dxi-item dataField="email"></dxi-item> <dxi-item dataField="telephone"></dxi-item> </dxi-item> <dxi-item itemType="group" caption="Partenariat"> <dxi-item dataField="partenaire"></dxi-item> <dxi-item dataField="clefEchange"></dxi-item> </dxi-item> <dxi-item itemType="group" caption="Quota"> <dxi-item editorType="dxNumberBox" [editorOptions]="{ showSpinButtons:true, showClearButton: true, min:100, max: 1024 }" dataField="documentsClientQuota"></dxi-item> </dxi-item> <dxi-item itemType="group" caption="Méta"> <dxi-item dataField="dateCreation"></dxi-item> <dxi-item dataField="dateEdition"></dxi-item> </dxi-item> </dxo-form> </dxo-popup> </dxo-editing> <dxi-column cssClass="align-cell-vertical" width="auto" cssClass="logoclient" dataField="logo" cellTemplate="cellTemplate" editCellTemplate="editCellTemplate" dataType="string" [allowSorting]="false" [visible]="true" [formItem]="{visible: true}" caption="Logo"> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataField="nom" caption="Nom"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataField="activite"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataField="email"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataField="telephone"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataField="referentPrincipal" [visible]="false"> <dxo-lookup [dataSource]="utilisateurDataSource" displayExpr="fullname" valueExpr="id"> </dxo-lookup> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataField="archive" [width]="70" dataType="boolean" [visible]="false"></dxi-column> <div *dxTemplate="let cell of 'cellTemplate'"> <img class="logoclient" *ngIf="cell.data.logo != null" [src]="cell.data.logo" [width]="64" [height]="64" /> </div> <div *dxTemplate="let cell of 'editCellTemplate'"> <img *ngIf="cell.value != null" [src]="cell.value" [width]="150" [height]="150" /> <dx-file-uploader #up selectButtonText="Select logo" labelText="" accept="image/*" uploadMode="useForm" [showFileList]="false" (onValueChanged)="onFileUploaderValueChanged($event, cell)"> </dx-file-uploader> </div> <dxi-column [visible]="false" dataField="dateEdition" caption="Dernière édition" [width]="70" [formItem]="{editorOptions: { readOnly: true }}"></dxi-column> <dxi-column [visible]="false" dataField="dateCreation" caption="Date de création" [width]="70" [formItem]="{editorOptions: { readOnly: true }}"></dxi-column> <dxi-column cssClass="align-cell-vertical" dataType="date" dataField="modelDateDebut"> </dxi-column> <dxi-column cssClass="align-cell-vertical" dataType="date" dataField="modelDateFin"> </dxi-column> </dx-data-grid>

and the component.ts file :

JavaScript
import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from "@angular/router"; import { ClientService } from 'app/services/client.service'; import { UserService } from 'app/services/user.service'; import { SiteService } from 'app/services/site.service'; import { UtilisateurService } from 'app/services/utilisateur.service'; import { TaxonomieService } from 'app/services/taxonomie.service' import { DxButtonModule, DxFormModule, DxFormComponent, DxListModule, DxToolbarModule, DxSelectBoxModule, DxCheckBoxModule, DxContextMenuModule, DxFileUploaderModule, DxSwitchModule, DxTextAreaModule, DxDropDownBoxModule, DxTagBoxModule, DxNumberBoxModule } from 'devextreme-angular' import { DxDataGridComponent } from "devextreme-angular"; import { DxButtonComponent } from "devextreme-angular"; // http://plnkr.co/edit/2ZY57Vi0yMX6qAjHhkxr?p=preview // https://js.devexpress.com/Demos/WidgetsGallery/Demo/Validation/Overview/Angular/Contrast/ // var myLoadOptions = grid.option('dataSource').loadOptions(); // !! https://www.devexpress.com/Support/Center/Question/Details/T518736/dxdatagrid-valuechanged-event-for-dxo-lookup-column-is-slow @Component({ selector: 'app-clients', templateUrl: './clients.component.html', styleUrls: ['./clients.component.scss'] }) export class ClientsComponent implements OnInit { @ViewChild('clientGrid') clientGrid: DxDataGridComponent; @ViewChild('siteGrid') siteGrid: DxDataGridComponent; @ViewChild('utilisateurGrid') utilisateurGrid: DxDataGridComponent; // data sources clientDataSource: any; siteDataSource: any; utilisateurDataSource: any; contratDataSource: any; veillesDataSource: any; // showArchive : boolean = false; // selections currentClient: number = 0; constructor( private userService: UserService, private route: ActivatedRoute, private clientService: ClientService, private siteService: SiteService, private utilisateuService: UtilisateurService, private taxoService : TaxonomieService ) { this.route.params.subscribe(params => console.log(params)); this.clientDataSource = clientService.getRestDataSource(); this.siteDataSource = siteService.getRestDataSource(); this.contratDataSource = siteService.getContratDataSource(); this.veillesDataSource = taxoService.getRestDataSource(); this.utilisateurDataSource = utilisateuService.getRestDataSource(); } ngOnInit() { } switch_onValueChanged(event) { this.showArchive = event.value; this.clientDataSource.load( { "filter": ["archive", "=", (this.showArchive ? 1 : 0)] } ); this.clientGrid.instance.refresh(); } grid_onEditorPreparing(e) { if (e.dataField === "activite" ) e.editorName = "dxTextArea"; } onTagBoxValueChanged(evt: any, data: any): void { data.setValue(evt.value); console.log("eonTagBoxValueChanged ", evt); } client_grid_onSelectionChanged(e) { console.log(e); } grid_utilisateur_onInitNewRow(e) { e.data.client = this.currentClient; } onFileUploaderValueChanged(event, cell) { if (event.value && event.value[0]) { let file = event.value[0]; let filename = file.name.split('.'); if (filename.length != 2) { console.error("Invalid Filename"); return; } let name = file[0]; let ext = file[1]; let reader = new FileReader(); reader.onload = () => { cell.setValue(reader.result); } reader.readAsDataURL(file); } } }

Answers approved by DevExpress Support

created 7 years ago (modified 7 years ago)

Hi,

It looks like the data is fetched two times because you refresh it at the datasource level and at the grid level simultaneously:

JavaScript
this.clientDataSource.load( { "filter": ["archive", "=", (this.showArchive ? 1 : 0)] } ); this.clientGrid.instance.refresh();

It should be sufficient to apply filtering at the grid level by using the filter method. Then, if the emoteOperations.filtering option is enabled, this operation will be performed on the server side. Otherwise, it will be performed at the local memory data cache level.

If this does not help you, please modify the Filtering API demo (use the "Copy to Plunker" button) to illustrate the glitch.

Thanks,
Alessandro

    Comments (1)

      Thank you ! it was the remote operation that was not set.

      <dxo-remote-operations [filtering]="true">

      made it work.

      Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

      Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.