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