刷新 Syncfusion Grid 后如何聚焦更新的记录
How to focus the updated record after refreshing a Syncfusion Grid
我一直在我的 angular (v.6.0.8) 项目中使用 Syncfusion 网格。在其中一个页面中,用户可以通过复选框将月份标记为已完成。
它会导致模型中的某些状态发生变化。因此,在后端调用完成后,我使用 "splice" 更新模型。为了反映网格上的变化,我必须调用 this.deliveryItemsGrid.refresh();但是,这会导致丢失用户正在处理的位置(网格向上滚动到顶部)。
有没有一种方法可以在不改变滚动条位置的情况下刷新网格?
[HTML]
<!-- JAN -->
<e-column headerText="JAN" [customAttributes]="{class: 'textAlignment'}">
<ng-template #template let-data>
<div> <i class="fa fa-wrench fa-2x" [style.color]="getMonthColorRM(data, 0)"></i></div>
<div *ngIf="!isReadOnlyUser" class="custom-control custom-checkbox">
<input id="chkChangeStatusRM{{data.rmDetailId + 'JAN'}}" type="checkbox" class="custom-control-input"
[checked]="getMonthCompletionStatus(data, 0)" (change)="saveStatusRM(data,'0')" aria-label="Complete Task" />
<label *ngIf="getMonthCompletionStatus(data, 0)" class="custom-control-label rm-month" for="chkChangeStatusRM{{data.rmDetailId + 'JAN'}}" data-toggle="tooltip" data-placement="top" title="Mark as not complete"></label>
<label *ngIf="!getMonthCompletionStatus(data, 0)" class="custom-control-label rm-month" for="chkChangeStatusRM{{data.rmDetailId + 'JAN'}}" data-toggle="tooltip" data-placement="top" title="Mark as complete"></label>
</div>
<div *ngIf="data.type != 'RM' && ((data?.plannedDate?.getMonth()) == 0)"> <i id="{{'JAN'+ data.type + data.id}}" class="fa fa-wrench fa-2x" [style.color]="getMonthColorCM(data)"></i></div>
</ng-template>
</e-column>
[ts 文件]
private saveStatusRM(row: DeliveryPlanModel, monthId) {
if (row && row.rmYears) {
let selectedRmYear: IYearModel = row.rmYears.filter(y => y.year == this.selectedYear.toString())[0];
selectedRmYear.schoolNumber = this.schoolNumber;
selectedRmYear.completedMonthsList.filter(m => m.month == monthId)[0].completed = !selectedRmYear.completedMonthsList.filter(m => m.month == monthId)[0].completed;
selectedRmYear.completed = selectedRmYear.completedMonthsList.every(m => m.completed);
if (selectedRmYear.completed)
row.statusDisplay = "Completed";
else {
if (selectedRmYear.completedMonthsList.some(m => m.completed))
row.statusDisplay = "In progress";
else
row.statusDisplay = "Planned";
}
// Set the color of the spanners (This is only for front-end use)
selectedRmYear.completedMonthsList.forEach(x => {
let color: string = "";
if (x.completed) {
color = "green";
}
else {
let dueOn: Date = new Date(+selectedRmYear.year, +x.month + 1, 1);
let currentDate: Date = new Date();
color = currentDate < dueOn ? "black" : "red";
}
x.color = color;
})
// Update the record on the Database.
this.deliveryPlanService.updateStatusRM(selectedRmYear).subscribe(
data => {
if (data) {
// Replace the updated record in 'gridRows'
var selectedRow = this.gridRows.filter(x => x.rmDetailId == row.rmDetailId)[0]
var selectedRecordIndex = this.gridRows.indexOf(selectedRow);
this.gridRows.splice(selectedRecordIndex, 1, row);
this.calculateRmProgress(this.gridRows);
//this.deliveryItemsGrid.refresh();
}
});
}
}
private getMonthCompletionStatus(row: DeliveryPlanModel, monthId): boolean {
if (row && row.rmYears) {
let selectedRmYear: IYearModel = row.rmYears.filter(y => y.year == this.selectedYear.toString())[0];
if (selectedRmYear && selectedRmYear.completedMonthsList) {
var month = selectedRmYear.completedMonthsList.filter(m => m.month == monthId)[0];
return month ? month.completed : null;
}
else {
return null;
}
}
}
我们已经分析了您的查询,我们建议在调用刷新方法之前获取 scrollTop 值,并在刷新操作完成后使用 actionComplete 事件将其绑定到网格滚动条。请参考以下示例和文档供您参考,
complete(args){
if(args.requestType == 'refresh' && this.scrollVal){
this.grid.getContent().firstElementChild.scrollTop = this.scrollVal;
this.scrollVal = 0;
}
}
refresh(){
this.scrollVal = this.grid.getContent().firstElementChild.scrollTop;
this.grid.refresh();
}
示例:https://stackblitz.com/edit/angular-gg4hgd-hrxcwr?file=default.component.ts
文档:https://ej2.syncfusion.com/documentation/api/grid/#actioncomplete
如需进一步帮助,请回复我们。
此致,
Thavasianand S.
我找到了解决问题的办法。我使用 "rowDataBound"
和 "dataBound"
事件来实现这一点。请参考以下代码。
[HTML]
<ejs-grid #deliveryItemsGrid id="deliveryItemsGrid"
[dataSource]="gridRows"
[gridLines]="componentVariables.gridLines"
[allowPaging]="componentVariables.allowPaging"
[allowGrouping]="componentVariables.allowGrouping"
[allowSorting]="componentVariables.allowSorting"
[allowSelection]="componentVariables.allowSelection"
[allowTextWrap]="componentVariables.allowTextWrap"
[allowFiltering]="componentVariables.allowFiltering"
[pageSettings]="componentVariables.pageSettings"
[filterSettings]="componentVariables.filterOptions"
[selectedRowIndex]="selectedRowIndex"
[selectionSettings]="selectionOptions"
[toolbar]="componentVariables.toolbarOptions"
(toolbarClick)="toolbarClick($event)"
(rowDataBound)="rowDataBound($event)"
(dataBound)="dataBound($event)">
[ts]
我创建了两个全局变量,用于存储选定的索引。
selectedIndexes: number[] = [];
justNowUpdatedId = 0;
然后,在所有更新函数中,在调用refresh()
方法之前,我将相关的id保存在'justNowUpdatedId'
变量中。
最后,我实现了 "rowDataBound"
和 "dataBound"
事件以保留用户之前工作的位置。
public rowDataBound(args): void {
if (args.data['type'] == 'RM' && args.data['rmDetailId'] == this.justNowUpdatedId ||
(args.data['type'] == 'CM' || args.data['type'] == 'DP' || args.data['type'] == 'CMC' || args.data['type'] == 'DPC') && args.data['id'] == this.justNowUpdatedId) {
this.selectedIndexes.push(parseInt(args.row.getAttribute('aria-rowindex')));
}
}
public dataBound(args): void {
if (this.selectedIndexes.length) {
this.deliveryItemsGrid.selectRows(this.selectedIndexes);
this.selectedIndexes = [];
}
}
我一直在我的 angular (v.6.0.8) 项目中使用 Syncfusion 网格。在其中一个页面中,用户可以通过复选框将月份标记为已完成。
它会导致模型中的某些状态发生变化。因此,在后端调用完成后,我使用 "splice" 更新模型。为了反映网格上的变化,我必须调用 this.deliveryItemsGrid.refresh();但是,这会导致丢失用户正在处理的位置(网格向上滚动到顶部)。
有没有一种方法可以在不改变滚动条位置的情况下刷新网格?
[HTML]
<!-- JAN -->
<e-column headerText="JAN" [customAttributes]="{class: 'textAlignment'}">
<ng-template #template let-data>
<div> <i class="fa fa-wrench fa-2x" [style.color]="getMonthColorRM(data, 0)"></i></div>
<div *ngIf="!isReadOnlyUser" class="custom-control custom-checkbox">
<input id="chkChangeStatusRM{{data.rmDetailId + 'JAN'}}" type="checkbox" class="custom-control-input"
[checked]="getMonthCompletionStatus(data, 0)" (change)="saveStatusRM(data,'0')" aria-label="Complete Task" />
<label *ngIf="getMonthCompletionStatus(data, 0)" class="custom-control-label rm-month" for="chkChangeStatusRM{{data.rmDetailId + 'JAN'}}" data-toggle="tooltip" data-placement="top" title="Mark as not complete"></label>
<label *ngIf="!getMonthCompletionStatus(data, 0)" class="custom-control-label rm-month" for="chkChangeStatusRM{{data.rmDetailId + 'JAN'}}" data-toggle="tooltip" data-placement="top" title="Mark as complete"></label>
</div>
<div *ngIf="data.type != 'RM' && ((data?.plannedDate?.getMonth()) == 0)"> <i id="{{'JAN'+ data.type + data.id}}" class="fa fa-wrench fa-2x" [style.color]="getMonthColorCM(data)"></i></div>
</ng-template>
</e-column>
[ts 文件]
private saveStatusRM(row: DeliveryPlanModel, monthId) {
if (row && row.rmYears) {
let selectedRmYear: IYearModel = row.rmYears.filter(y => y.year == this.selectedYear.toString())[0];
selectedRmYear.schoolNumber = this.schoolNumber;
selectedRmYear.completedMonthsList.filter(m => m.month == monthId)[0].completed = !selectedRmYear.completedMonthsList.filter(m => m.month == monthId)[0].completed;
selectedRmYear.completed = selectedRmYear.completedMonthsList.every(m => m.completed);
if (selectedRmYear.completed)
row.statusDisplay = "Completed";
else {
if (selectedRmYear.completedMonthsList.some(m => m.completed))
row.statusDisplay = "In progress";
else
row.statusDisplay = "Planned";
}
// Set the color of the spanners (This is only for front-end use)
selectedRmYear.completedMonthsList.forEach(x => {
let color: string = "";
if (x.completed) {
color = "green";
}
else {
let dueOn: Date = new Date(+selectedRmYear.year, +x.month + 1, 1);
let currentDate: Date = new Date();
color = currentDate < dueOn ? "black" : "red";
}
x.color = color;
})
// Update the record on the Database.
this.deliveryPlanService.updateStatusRM(selectedRmYear).subscribe(
data => {
if (data) {
// Replace the updated record in 'gridRows'
var selectedRow = this.gridRows.filter(x => x.rmDetailId == row.rmDetailId)[0]
var selectedRecordIndex = this.gridRows.indexOf(selectedRow);
this.gridRows.splice(selectedRecordIndex, 1, row);
this.calculateRmProgress(this.gridRows);
//this.deliveryItemsGrid.refresh();
}
});
}
}
private getMonthCompletionStatus(row: DeliveryPlanModel, monthId): boolean {
if (row && row.rmYears) {
let selectedRmYear: IYearModel = row.rmYears.filter(y => y.year == this.selectedYear.toString())[0];
if (selectedRmYear && selectedRmYear.completedMonthsList) {
var month = selectedRmYear.completedMonthsList.filter(m => m.month == monthId)[0];
return month ? month.completed : null;
}
else {
return null;
}
}
}
我们已经分析了您的查询,我们建议在调用刷新方法之前获取 scrollTop 值,并在刷新操作完成后使用 actionComplete 事件将其绑定到网格滚动条。请参考以下示例和文档供您参考,
complete(args){
if(args.requestType == 'refresh' && this.scrollVal){
this.grid.getContent().firstElementChild.scrollTop = this.scrollVal;
this.scrollVal = 0;
}
}
refresh(){
this.scrollVal = this.grid.getContent().firstElementChild.scrollTop;
this.grid.refresh();
}
示例:https://stackblitz.com/edit/angular-gg4hgd-hrxcwr?file=default.component.ts
文档:https://ej2.syncfusion.com/documentation/api/grid/#actioncomplete
如需进一步帮助,请回复我们。
此致, Thavasianand S.
我找到了解决问题的办法。我使用 "rowDataBound"
和 "dataBound"
事件来实现这一点。请参考以下代码。
[HTML]
<ejs-grid #deliveryItemsGrid id="deliveryItemsGrid"
[dataSource]="gridRows"
[gridLines]="componentVariables.gridLines"
[allowPaging]="componentVariables.allowPaging"
[allowGrouping]="componentVariables.allowGrouping"
[allowSorting]="componentVariables.allowSorting"
[allowSelection]="componentVariables.allowSelection"
[allowTextWrap]="componentVariables.allowTextWrap"
[allowFiltering]="componentVariables.allowFiltering"
[pageSettings]="componentVariables.pageSettings"
[filterSettings]="componentVariables.filterOptions"
[selectedRowIndex]="selectedRowIndex"
[selectionSettings]="selectionOptions"
[toolbar]="componentVariables.toolbarOptions"
(toolbarClick)="toolbarClick($event)"
(rowDataBound)="rowDataBound($event)"
(dataBound)="dataBound($event)">
[ts]
我创建了两个全局变量,用于存储选定的索引。
selectedIndexes: number[] = [];
justNowUpdatedId = 0;
然后,在所有更新函数中,在调用refresh()
方法之前,我将相关的id保存在'justNowUpdatedId'
变量中。
最后,我实现了 "rowDataBound"
和 "dataBound"
事件以保留用户之前工作的位置。
public rowDataBound(args): void {
if (args.data['type'] == 'RM' && args.data['rmDetailId'] == this.justNowUpdatedId ||
(args.data['type'] == 'CM' || args.data['type'] == 'DP' || args.data['type'] == 'CMC' || args.data['type'] == 'DPC') && args.data['id'] == this.justNowUpdatedId) {
this.selectedIndexes.push(parseInt(args.row.getAttribute('aria-rowindex')));
}
}
public dataBound(args): void {
if (this.selectedIndexes.length) {
this.deliveryItemsGrid.selectRows(this.selectedIndexes);
this.selectedIndexes = [];
}
}