1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import { Component } from 'vue-property-decorator';
import { AppGridBase } from '../app-common-control/app-grid-base';
import { VueLifeCycleProcessing } from '../../../decorators';
import { ModelTool, throttle } from 'ibiz-core';
import { IPSDEGridColumn, IPSDEGridEditItem, IPSDEGridFieldColumn, IPSEditor } from '@ibiz/dynamic-model-api';
/**
* 单元格编辑表格部件
* 行编辑只在点击单元格的时候绘制,减少性能压力
*
* @export
* @class AppCellEditGrid
* @extends {AppGridBase}
*/
@Component({})
@VueLifeCycleProcessing()
export class AppCellEditGrid extends AppGridBase {
/**
* 渲染完成
*
* @memberof AppDataViewBase
*/
public ctrlMounted() {
super.ctrlMounted();
// 绑定this,添加监听全局点击事件
this.clearCellEdit = this.clearCellEdit.bind(this);
window.addEventListener('click', this.clearCellEdit);
}
/**
* 执行destroyed后的逻辑
*
* @memberof MDControlBase
*/
public ctrlDestroyed() {
super.ctrlDestroyed();
window.removeEventListener('click', this.clearCellEdit);
}
/**
* 当前开启编辑的单元格element
*/
public currentEditCell: any = null;
/**
* 清空所有开启编辑的单元格
* @param event
*/
public clearCellEdit(event: any) {
// 当有单元格开启编辑,且点击不是当前单元格内部时,清空所有
if (this.currentEditCell && !this.currentEditCell.contains(event.target)) {
this.items.forEach((item: any) => {
item.editColumnName = undefined;
});
this.currentEditCell = null;
this.$forceUpdate();
}
}
/**
* 单元格点击事件回调
* @param row 行数据
* @param column 列信息
* @param cell 单元格元素
* @param event 事件
* @return {*}
*/
public cellClick(row: any, column: any, cell: any, event: any) {
// 阻止冒泡,因为编辑项重绘,导致cell内部已经没有event.target了。
event.stopPropagation();
// 已经开启的单元格不需要反复执行
if (this.currentEditCell == cell) {
return;
}
// 如果有其他已经开启的单元格,则先清除
if (this.currentEditCell && this.currentEditCell !== cell) {
this.clearCellEdit({ target: cell });
}
// 开启选中单元格的编辑项,并存储元素给clearCellEdit使用
row.editColumnName = column.property;
this.currentEditCell = cell;
this.$forceUpdate();
}
/**
* 计算表格事件
*
* @memberof AppGridBase
*/
public computeGridEvents() {
let events = super.computeGridEvents();
Object.assign(events, {
'cell-click': (row: any, column: any, cell: any, event: any) =>
throttle(this.cellClick, [row, column, cell, event], this),
});
return events;
}
/**
* 表格编辑项值变更
*
* @param row 行数据
* @param {{ name: string, value: any }} 变化数据键值
* @param rowIndex 行索引
* @memberof GridControlBase
*/
public onGridItemValueChange2(row: any, $event: { name: string, value: any }, rowIndex: number, item:any): void {
if (!$event) {
return;
}
if (!$event.name || Object.is($event.name, '') || !row.hasOwnProperty($event.name)) {
return;
}
row[$event.name] = $event.value;
// 列数据项值也需要更新
const dataItemName:any = item.dataItemName;
if (dataItemName) {
row[dataItemName] = $event.value;
}
this.gridEditItemChange(row, $event.name, $event.value, rowIndex);
}
/**
* 绘制编辑项
* @param item
* @param scope
* @return {*}
*/
public renderOpenEditItem(item: IPSDEGridColumn, scope: any) {
if (scope.row.editColumnName == scope.column.property) {
const editItem: IPSDEGridEditItem = ModelTool.getGridItemByCodeName(
item.codeName,
this.controlInstance,
) as IPSDEGridEditItem;
let editor: IPSEditor | null = editItem?.getPSEditor();
if (!editor) {
return null;
}
const valueFormat = (item as IPSDEGridFieldColumn).valueFormat;
const { row, column, $index } = scope;
return (
<app-form-item gridError={this.gridItemsModel[$index]?.[column.property]?.error}>
<app-default-editor
editorInstance={editor}
ref={editor.name}
parentItem={editItem}
value={row[editor?.name]}
disabled={this.getColumnDisabled(row, editor?.name)}
context={this.context}
contextData={row}
viewparams={this.viewparams}
valueFormat={valueFormat}
service={this.service}
on-change={(value: any) => {
this.onGridItemValueChange2(row, value, $index, item);
}}
/>
</app-form-item>
);
} else {
return this.renderColumn(item, scope);
}
}
}