Type interference for the DS
This commit is contained in:
parent
548e720795
commit
dc0c92253d
@ -1,4 +1,4 @@
|
||||
import { ModelConstructor } from '../../shared/models/base.model';
|
||||
import { ModelConstructor, BaseModel } from '../../shared/models/base.model';
|
||||
|
||||
/**
|
||||
* Registeres the mapping of collection strings <--> actual types. Every Model should register itself here.
|
||||
@ -8,14 +8,14 @@ export class CollectionStringModelMapperService {
|
||||
* Mapps collection strings to model constructors. Accessed by {@method registerCollectionElement} and
|
||||
* {@method getCollectionStringType}.
|
||||
*/
|
||||
private static collectionStringsTypeMapping: { [collectionString: string]: ModelConstructor } = {};
|
||||
private static collectionStringsTypeMapping: { [collectionString: string]: ModelConstructor<BaseModel> } = {};
|
||||
|
||||
/**
|
||||
* Registers the type to the collection string
|
||||
* @param collectionString
|
||||
* @param type
|
||||
*/
|
||||
public static registerCollectionElement(collectionString: string, type: ModelConstructor) {
|
||||
public static registerCollectionElement(collectionString: string, type: ModelConstructor<BaseModel>) {
|
||||
CollectionStringModelMapperService.collectionStringsTypeMapping[collectionString] = type;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ export class CollectionStringModelMapperService {
|
||||
* Returns the constructor of the requested collection or undefined, if it is not registered.
|
||||
* @param collectionString the requested collection
|
||||
*/
|
||||
public static getModelConstructor(collectionString: string): ModelConstructor {
|
||||
public static getModelConstructor(collectionString: string): ModelConstructor<BaseModel> {
|
||||
return CollectionStringModelMapperService.collectionStringsTypeMapping[collectionString];
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ export class CollectionStringModelMapperService {
|
||||
* Returns the collection string of a given ModelConstructor or undefined, if it is not registered.
|
||||
* @param ctor
|
||||
*/
|
||||
public static getCollectionString(ctor: ModelConstructor): string {
|
||||
public static getCollectionString(ctor: ModelConstructor<BaseModel>): string {
|
||||
return Object.keys(CollectionStringModelMapperService.collectionStringsTypeMapping).find(
|
||||
(collectionString: string) => {
|
||||
return ctor === CollectionStringModelMapperService.collectionStringsTypeMapping[collectionString];
|
||||
|
@ -182,7 +182,7 @@ export class DataStoreService {
|
||||
});
|
||||
}
|
||||
|
||||
private getCollectionString(collectionType: ModelConstructor | string): string {
|
||||
private getCollectionString<T extends BaseModel>(collectionType: ModelConstructor<T> | string): string {
|
||||
if (typeof collectionType === 'string') {
|
||||
return collectionType;
|
||||
} else {
|
||||
@ -197,10 +197,10 @@ export class DataStoreService {
|
||||
* @param ids One ID of the BaseModel
|
||||
* @return The given BaseModel-subclass instance
|
||||
* @example: this.DS.get(User, 1)
|
||||
* @example: this.DS.get('core/countdown', 2)
|
||||
* @example: this.DS.get<Countdown>('core/countdown', 2)
|
||||
*/
|
||||
public get<T extends BaseModel>(collectionType: ModelConstructor | string, id: number): T {
|
||||
const collectionString = this.getCollectionString(collectionType);
|
||||
public get<T extends BaseModel>(collectionType: ModelConstructor<T> | string, id: number): T {
|
||||
const collectionString = this.getCollectionString<T>(collectionType);
|
||||
|
||||
const collection: ModelCollection = this.modelStore[collectionString];
|
||||
if (!collection) {
|
||||
@ -211,14 +211,16 @@ export class DataStoreService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read multiple ID's from dataStore
|
||||
* Read multiple ID's from dataStore.
|
||||
*
|
||||
* @param collectionType The desired BaseModel or collectionString to be read from the dataStore
|
||||
* @param ids Multiple IDs as a list of IDs of BaseModel
|
||||
* @return The BaseModel-list corresponding to the given ID(s)
|
||||
* @example: this.DS.get(User, [1,2,3,4,5])
|
||||
* @example: this.DS.getMany(User, [1,2,3,4,5])
|
||||
* @example: this.DS.getMany<User>('users/user', [1,2,3,4,5])
|
||||
*/
|
||||
public getMany<T extends BaseModel>(collectionType: ModelConstructor | string, ids: number[]): T[] {
|
||||
const collectionString = this.getCollectionString(collectionType);
|
||||
public getMany<T extends BaseModel>(collectionType: ModelConstructor<T> | string, ids: number[]): T[] {
|
||||
const collectionString = this.getCollectionString<T>(collectionType);
|
||||
|
||||
const collection: ModelCollection = this.modelStore[collectionString];
|
||||
if (!collection) {
|
||||
@ -234,12 +236,14 @@ export class DataStoreService {
|
||||
|
||||
/**
|
||||
* Get all models of the given collection from the DataStore.
|
||||
*
|
||||
* @param collectionType The desired BaseModel or collectionString to be read from the dataStore
|
||||
* @return The BaseModel-list of all instances of T
|
||||
* @example: this.DS.get(User)
|
||||
* @example: this.DS.getAll(User)
|
||||
* @example: this.DS.getAll<User>('users/user')
|
||||
*/
|
||||
public getAll<T extends BaseModel>(collectionType: ModelConstructor | string): T[] {
|
||||
const collectionString = this.getCollectionString(collectionType);
|
||||
public getAll<T extends BaseModel>(collectionType: ModelConstructor<T> | string): T[] {
|
||||
const collectionString = this.getCollectionString<T>(collectionType);
|
||||
|
||||
const collection: ModelCollection = this.modelStore[collectionString];
|
||||
if (!collection) {
|
||||
@ -258,14 +262,15 @@ export class DataStoreService {
|
||||
* @example this.DS.filter<User>(User, myUser => myUser.first_name === "Max")
|
||||
*/
|
||||
public filter<T extends BaseModel>(
|
||||
collectionType: ModelConstructor | string,
|
||||
collectionType: ModelConstructor<T> | string,
|
||||
callback: (model: T) => boolean
|
||||
): T[] {
|
||||
return this.getAll<T>(collectionType).filter(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one or multiple models to dataStore
|
||||
* Add one or multiple models to dataStore.
|
||||
*
|
||||
* @param ...models The model(s) that shall be add use spread operator ("...")
|
||||
* @example this.DS.add(new User(1))
|
||||
* @example this.DS.add((new User(2), new User(3)))
|
||||
@ -296,7 +301,8 @@ export class DataStoreService {
|
||||
}
|
||||
|
||||
/**
|
||||
* removes one or multiple models from dataStore
|
||||
* removes one or multiple models from dataStore.
|
||||
*
|
||||
* @param Type The desired BaseModel type to be read from the dataStore
|
||||
* @param ...ids An or multiple IDs or a list of IDs of BaseModels. use spread operator ("...") for arrays
|
||||
* @example this.DS.remove(User, myUser.id, 3, 4)
|
||||
|
@ -140,7 +140,7 @@ export class OperatorService extends OpenSlidesComponent {
|
||||
private updatePermissions(): void {
|
||||
this.permissions = [];
|
||||
if (!this.user) {
|
||||
const defaultGroup = this.DS.get('users/group', 1) as Group;
|
||||
const defaultGroup = this.DS.get<Group>('users/group', 1);
|
||||
if (defaultGroup && defaultGroup.permissions instanceof Array) {
|
||||
this.permissions = defaultGroup.permissions;
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ import { OpenSlidesComponent } from 'app/openslides.component';
|
||||
import { Deserializable } from './deserializable.model';
|
||||
import { CollectionStringModelMapperService } from '../../core/services/collectionStringModelMapper.service';
|
||||
|
||||
export interface ModelConstructor {
|
||||
new (...args: any[]): BaseModel;
|
||||
export interface ModelConstructor<T extends BaseModel> {
|
||||
new (...args: any[]): T;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { BaseModel } from '../base.model';
|
||||
import { Item } from '../agenda/item';
|
||||
|
||||
/**
|
||||
* Representation of a motion block.
|
||||
@ -19,7 +20,7 @@ export class MotionBlock extends BaseModel {
|
||||
}
|
||||
|
||||
public getAgenda(): BaseModel | BaseModel[] {
|
||||
return this.DS.get('agenda/item', this.agenda_item_id);
|
||||
return this.DS.get<Item>('agenda/item', this.agenda_item_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ export class Motion extends BaseModel {
|
||||
*/
|
||||
public initDataStoreValues() {
|
||||
// check the containing Workflows in DataStore
|
||||
const allWorkflows = this.DS.getAll<Workflow>(Workflow);
|
||||
const allWorkflows = this.DS.getAll(Workflow);
|
||||
allWorkflows.forEach(localWorkflow => {
|
||||
if (localWorkflow.isStateContained(this.state_id)) {
|
||||
this.workflow = localWorkflow as Workflow;
|
||||
|
@ -34,7 +34,7 @@ export class User extends BaseModel {
|
||||
}
|
||||
|
||||
public get groups(): Group[] {
|
||||
return this.DS.getMany<Group>(Group, this.groups_id);
|
||||
return this.DS.getMany(Group, this.groups_id);
|
||||
}
|
||||
|
||||
public get full_name(): string {
|
||||
|
@ -53,7 +53,7 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
|
||||
*/
|
||||
public ngOnInit() {
|
||||
super.setTitle('Category');
|
||||
this.categoryArray = this.DS.getAll<Category>(Category);
|
||||
this.categoryArray = this.DS.getAll(Category);
|
||||
this.dataSource = new MatTableDataSource(this.categoryArray);
|
||||
this.dataSource.sort = this.sort;
|
||||
|
||||
@ -61,7 +61,7 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
|
||||
// The alternative approach is to put the observable as DataSource to the table
|
||||
this.DS.changeObservable.subscribe(newModel => {
|
||||
if (newModel instanceof Category) {
|
||||
this.categoryArray = this.DS.getAll<Category>(Category);
|
||||
this.categoryArray = this.DS.getAll(Category);
|
||||
this.dataSource.data = this.categoryArray;
|
||||
}
|
||||
});
|
||||
|
@ -88,7 +88,7 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
||||
// load existing motion
|
||||
this.route.params.subscribe(params => {
|
||||
// has the motion of the DataStore was initialized before.
|
||||
this.motion = this.DS.get(Motion, params.id) as Motion;
|
||||
this.motion = this.DS.get(Motion, params.id);
|
||||
|
||||
// Observe motion to get the motion in the parameter and also get the changes
|
||||
this.DS.changeObservable.subscribe(newModel => {
|
||||
@ -165,7 +165,7 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
||||
* return all Categories.
|
||||
*/
|
||||
public getMotionCategories(): Category[] {
|
||||
return this.DS.getAll<Category>(Category);
|
||||
return this.DS.getAll(Category);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,8 +93,8 @@ export class MotionListComponent extends BaseComponent implements OnInit {
|
||||
*/
|
||||
public ngOnInit() {
|
||||
super.setTitle('Motions');
|
||||
this.workflowArray = this.DS.getAll<Workflow>(Workflow);
|
||||
this.motionArray = this.DS.getAll<Motion>(Motion);
|
||||
this.workflowArray = this.DS.getAll(Workflow);
|
||||
this.motionArray = this.DS.getAll(Motion);
|
||||
this.dataSource = new MatTableDataSource(this.motionArray);
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
@ -103,7 +103,7 @@ export class MotionListComponent extends BaseComponent implements OnInit {
|
||||
// The alternative approach is to put the observable as DataSource to the table
|
||||
this.DS.changeObservable.subscribe(newModel => {
|
||||
if (newModel instanceof Motion) {
|
||||
this.motionArray = this.DS.getAll<Motion>(Motion);
|
||||
this.motionArray = this.DS.getAll(Motion);
|
||||
this.dataSource.data = this.motionArray;
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user