feat(collection-manger): lazy load collection field (#1993)

* feat(collection-manger): lazy load collection field

* chore: console.log
This commit is contained in:
ChengLei Shao 2023-06-06 22:48:43 +08:00 committed by GitHub
parent 42ad77da68
commit c604f37222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 4 deletions

View File

@ -5,7 +5,7 @@ import { FieldModel } from './field';
interface LoadOptions extends Transactionable {
// TODO
skipField?: boolean;
skipField?: boolean | Array<string>;
skipExist?: boolean;
}
@ -41,6 +41,10 @@ export class CollectionModel extends MagicAttributeModel {
await this.loadFields({ transaction });
}
if (lodash.isArray(skipField)) {
await this.loadFields({ transaction, skipField });
}
await this.db.emitAsync('collection:loaded', {
collection,
transaction,
@ -49,11 +53,26 @@ export class CollectionModel extends MagicAttributeModel {
return collection;
}
async loadFields(options: Transactionable = {}) {
async loadFields(
options: Transactionable & {
skipField?: Array<string>;
includeFields?: Array<string>;
} = {},
) {
let fields = this.get('fields') || [];
if (!fields.length) {
fields = await this.getFields(options);
}
if (options.skipField) {
fields = fields.filter((field) => !options.skipField.includes(field.name));
}
if (options.includeFields) {
fields = fields.filter((field) => options.includeFields.includes(field.name));
}
// @ts-ignore
const instances: FieldModel[] = fields;

View File

@ -1,6 +1,7 @@
import { Repository } from '@nocobase/database';
import { CollectionsGraph } from '@nocobase/utils';
import { CollectionModel } from '../models/collection';
import lodash from 'lodash';
interface LoadOptions {
filter?: any;
@ -16,7 +17,9 @@ export class CollectionRepository extends Repository {
const graph = new graphlib.Graph();
const nameMap = {};
const nameMap: {
[key: string]: CollectionModel;
} = {};
const viewCollections = [];
@ -60,15 +63,40 @@ export class CollectionRepository extends Repository {
const sortedNames = graphlib.alg.topsort(graph);
const lazyCollectionFields: {
[key: string]: Array<string>;
} = {};
for (const instanceName of sortedNames) {
if (!nameMap[instanceName]) continue;
await nameMap[instanceName].load({ skipExist, skipField: viewCollections.includes(instanceName) });
const skipField = (() => {
if (viewCollections.includes(instanceName)) {
return true;
}
const fields = nameMap[instanceName].get('fields');
return fields
.filter((field) => field['type'] === 'belongsTo' && viewCollections.includes(field.options?.['target']))
.map((field) => field.get('name'));
})();
if (lodash.isArray(skipField) && skipField.length) {
lazyCollectionFields[instanceName] = skipField;
}
await nameMap[instanceName].load({ skipField });
}
// load view fields
for (const viewCollectionName of viewCollections) {
await nameMap[viewCollectionName].loadFields({});
}
// load lazy collection field
for (const [collectionName, skipField] of Object.entries(lazyCollectionFields)) {
await nameMap[collectionName].loadFields({ includeFields: skipField });
}
}
async db2cm(collectionName: string) {