问题
app.component.html
<div class="inlineBlock">
<select [(ngModel)]="portId" id="portDropdownMenu" (change)="externalFilterChanged()">
<option *ngFor="#portId of portIds">{{portId}}</option>
</select>
</div>
<div class="container">
<ag-grid-ng2 #agGrid
[gridOptions]="gridOptions"
[columnDefs]="myColumnDefs"
[rowData]="myRowData"
enableColResize
rowSelection="multiple"
enableSorting
enableFilter
[isExternalFilterPresent]="isExternalFilterPresent"
[doesExternalFilterPass]="doesExternalFilterPass"
rowHeight="30"
headerHeight="40"
enableRangeSelection
suppressContextMenu
suppressMenuColumnPanel
rowGroupPanelShow="always"
rememberGroupStateWhenNextData
groupDefaultExpanded="-1"
groupHideGroupColumns
groupUseEntireRow
(modelUpdated)="onModelUpdated()"
(filterChanged)="onFilterChanged()">
</ag-grid-ng2>
</div>
app.component.ts
public isExternalFilterPresent() {
return this.portType != "All Ports";
}
public doesExternalFilterPass(node) {
switch (this.portType) {
case "1": return node.data.Port === "1";
case "2": return node.data.Port === "2";
case "3": return node.data.Port === "3";
default: return true;
}
}
public externalFilterChanged() {
var newValue = (<HTMLInputElement>document.getElementById("portDropdownMenu")).value
this.portType = newValue;
this.gridOptions.api.onFilterChanged();
}
public onFilterChanged() {
if (this.gridOptions.api.isAnyFilterPresent()) {
this.gridOptions.api.setRowData(this.gridOptions.rowData);
this.gridOptions.api.refreshView();
}
console.log("filter changed ...");
}
By console.log(this.gridOption.isAnyFilterPresented()), I notice the filter does exist when dropdown menu is updated. However, the grid is not updating according to external filter.
I am pretty sure "isExternalFilterPresent()" and "doesExternalFilterPass(node)" run through and provides the correct return value. My understanding is that ag-grid will take care of the rest but it is not doing it. Any idea?
回答1:
there is a solution to this issue.
declare the two functions: isExternalFilterPresent,doesExternalFilterPass in type script,
get an instance of the gridOptions,
private gridOptions:GridOptions;
and in the constructor:
this.gridOptions = <GridOptions>{};
then
this.gridOptions.isExternalFilterPresent = this.isExternalFilterPresent.bind(this);
this.gridOptions.doesExternalFilterPass = this.doesExternalFilterPass.bind(this);
now, you will be able to access the component's variables inside those functions:
this.myVariable
full description the problem+solution: https://github.com/ceolter/ag-grid-ng2/issues/121
回答2:
doesExternalFilterPass
and isExternalFilterPresent
are an arrow function so this
has no meaning inside these functions. Below is how they should be used -
/**
* This property is an arrow function, which binds `this` to the Angular Component.
* It's necessary otherwise `this` is undefined inside the function because
* it's not called as a method of the class by the Datagrid.
* It's called as `doesExternalFilterPass(node)` and not as `component.doesExternalFilterPass(node)`
*/
doesExternalFilterPass = (node: RowNode): boolean => {
return node.data.currency >= this.currencyFilter;
}
Source - https://github.com/ceolter/ag-grid-angular/issues/121
回答3:
An update on this issue:
The problem for me is the scope in angular 2 variables. "this.portType" is undefined in "isExternalFilterPresent()" and "doesExternalFilterPass(node)" even I initialized properly in the constructor. My fix is to retrieve portType from html each time those two functions are called.
It is not a nice fix, hopefully someone could come up with something better. And if anyone could explain why portType variable was undefined?
来源:https://stackoverflow.com/questions/37957310/ag-grid-external-filter-in-angular-2-filter-presents-but-grid-not-updating