静态列表
静态列表(StaticList)是数据点的子类,是用来实现静态列表的数据结构。
Setup函数
我们来看静态列表的Setup函数:
setup(config, data, options = {}) {
this._parent = options.parent;
this._onUpdate = options.onUpdate;
this._cache = markRaw({});
this._commands = [];
this._initialCommands = [];
this._savePoint = undefined;
this._unknownRecordCommands = {}; // tracks update commands on records we haven't fetched yet
this._currentIds = [...this.resIds];
this._initialCurrentIds = [...this.currentIds];
this._needsReordering = false;
this._tmpIncreaseLimit = 0;
// In kanban and non editable list views, x2many records can be opened in a form view in
// dialog, which may contain other fields than the kanban or list view. The next set keeps
// tracks of records we already opened in dialog and thus for which we already modified the
// config to add the form view's fields in activeFields.
this._extendedRecords = new Set();
this.records = data
.slice(this.offset, this.limit)
.map((r) => this._createRecordDatapoint(r));
this.count = this.resIds.length;
this.handleField = Object.keys(this.activeFields).find(
(fieldName) => this.activeFields[fieldName].isHandle
);
}
Setup函数对静态表对象做了一些初始化的操作,例如挂在父类属性和_onUpdate事件。由Setup函数我们可以直到静态列表对象拥有以下属性:
- records: 数据记录集
- count:数据集长度
- handleField:是否是可拖拽字段
访问器方法
静态列表拥有的访问器方法如下:
get currentIds() {
return this._currentIds;
}
get editedRecord() {
return this.records.find((record) => record.isInEdition);
}
get evalContext() {
const evalContext = getBasicEvalContext(this.config);
evalContext.parent = this._parent.evalContext;
return evalContext;
}
get limit() {
return this.config.limit;
}
get offset() {
return this.config.offset;
}
get orderBy() {
return this.config.orderBy;
}
get resIds() {
return this.config.resIds;
}
- currentIds: 当前数据的ID
- editedRecord:是否存在已经编辑过还未提交的记录
- evalContext:上下文
- limit:数据限制长度
- offset:偏离参数
- orderBy:排序字段
- resIds:资源ID
公共方法
数据列表还提供了以下公共方法:
addNewRecord
addNewRecord方法用来添加新记录。
addNewRecord(params) {
return this.model.mutex.exec(async () => {
const { activeFields, context, mode, position, withoutParent } = params;
const record = await this._createNewRecordDatapoint({
activeFields,
context,
position,
withoutParent,
manuallyAdded: true,
mode,
});
await this._addRecord(record, { position });
await this._onUpdate({ withoutOnchange: !record._checkValidity({ silent: true }) });
return record;
});
}
此方法接收一个param参数,返回一个新增的记录对象record。其内部实现是,先使用私有_createNewRecordDatapoint方法创建一个数据点,然后使用_addRecord方法将此数据点添加为记录record,然后使用_onUpdate方法通知系统数据变化。
canResequence
canResequence() {
return this.handleField && this.orderBy.length && this.orderBy[0].name === this.handleField;
}
canResequence方法用来判断,此静态列表是否可以被拖拽排序。其判断依据是,排序字段列表有值且第一个字段为可拖拽字段。
delete
delete(record) {
return this.model.mutex.exec(async () => {
await this._applyCommands([[x2ManyCommands.DELETE, record.resId || record._virtualId]]);
await this._onUpdate();
});
}
删除本记录。
enterEditMode
async enterEditMode(record) {
const canProceed = await this.leaveEditMode();
if (canProceed) {
await record.switchMode("edit");
}
return canProceed;
}
进入编辑模式。
extendRecord
extendRecord(params, record) {
...
}
extendRecord方法仅在X2many字段在对话框中显示时适用,通常情况下这种对话框内使用的是不同于本记录的对象模型,因为需要拓展字段的记录,将对话框使用的对象模型集成进来。
forget
forget(record) {
return this.model.mutex.exec(async () => {
await this._applyCommands([[x2ManyCommands.UNLINK, record.resId]]);
await this._onUpdate();
});
}
后端UNLNK方法的WC实现。
leaveEditMode
async leaveEditMode({ discard, canAbandon, validate } = {}) {
if (this.editedRecord) {
await this.model._askChanges(false);
}
return this.model.mutex.exec(async () => {
if (this.editedRecord) {
const isValid = this.editedRecord._checkValidity();
if (!isValid && validate) {
return false;
}
if (canAbandon !== false && !validate) {
this._abandonRecords([this.editedRecord], { force: true });
}
// if we still have an editedRecord, it means it hasn't been abandonned
if (this.editedRecord) {
if (isValid && !this.editedRecord.dirty && discard) {
return false;
}
if (
isValid ||
(!this.editedRecord.dirty && !this.editedRecord._manuallyAdded)
) {
this.editedRecord._switchMode("readonly");
}
}
}
return !this.editedRecord;
});
}
此方法用来判断是否可以离开编辑模式。