Merge pull request #3857 from FinnStutzenstein/delete-observable

changed and deleted observable for the datastore. Removed ModelId
This commit is contained in:
Finn Stutzenstein 2018-09-10 08:33:20 +02:00 committed by GitHub
commit 3b57fbcd8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 39 deletions

View File

@ -34,7 +34,7 @@ export class ConfigService extends OpenSlidesComponent {
public constructor() { public constructor() {
super(); super();
this.DS.getObservable().subscribe(data => { this.DS.changeObservable.subscribe(data => {
// on changes notify the observers for specific keys. // on changes notify the observers for specific keys.
if (data instanceof Config && this.configSubjects[data.key]) { if (data instanceof Config && this.configSubjects[data.key]) {
this.configSubjects[data.key].next(data.value); this.configSubjects[data.key].next(data.value);

View File

@ -1,10 +1,20 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { BaseModel, ModelId, ModelConstructor } from 'app/shared/models/base.model'; import { BaseModel, ModelConstructor } from 'app/shared/models/base.model';
import { CacheService } from './cache.service'; import { CacheService } from './cache.service';
import { CollectionStringModelMapperService } from './collectionStringModelMapper.service'; import { CollectionStringModelMapperService } from './collectionStringModelMapper.service';
/**
* Represents information about a deleted model.
*
* As the model doesn't exist anymore, just the former id and collection is known.
*/
export interface DeletedInformation {
collection: string;
id: number;
}
/** /**
* represents a collection on the Django server, uses an ID to access a {@link BaseModel}. * represents a collection on the Django server, uses an ID to access a {@link BaseModel}.
* *
@ -62,9 +72,32 @@ export class DataStoreService {
private JsonStore: JsonStorage = {}; private JsonStore: JsonStorage = {};
/** /**
* Observable subject with changes to enable dynamic changes in models and views * Observable subject for changed models in the datastore.
*/ */
private dataStoreSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null); private changedSubject: Subject<BaseModel> = new Subject<BaseModel>();
/**
* Observe the datastore for changes.
*
* @return an observable for changed models
*/
public get changeObservable(): Observable<BaseModel> {
return this.changedSubject.asObservable();
}
/**
* Observable subject for changed models in the datastore.
*/
private deletedSubject: Subject<DeletedInformation> = new Subject<DeletedInformation>();
/**
* Observe the datastore for deletions.
*
* @return an observable for deleted objects.
*/
public get deletedObservable(): Observable<DeletedInformation> {
return this.deletedSubject.asObservable();
}
/** /**
* The maximal change id from this DataStore. * The maximal change id from this DataStore.
@ -166,14 +199,14 @@ export class DataStoreService {
* @example: this.DS.get(User, 1) * @example: this.DS.get(User, 1)
* @example: this.DS.get('core/countdown', 2) * @example: this.DS.get('core/countdown', 2)
*/ */
public get<T extends BaseModel>(collectionType: ModelConstructor | string, id: ModelId): T { public get<T extends BaseModel>(collectionType: ModelConstructor | string, id: number): T {
const collectionString = this.getCollectionString(collectionType); const collectionString = this.getCollectionString(collectionType);
const collection: ModelCollection = this.modelStore[collectionString]; const collection: ModelCollection = this.modelStore[collectionString];
if (!collection) { if (!collection) {
return; return;
} else { } else {
return collection[id]; return collection[id] as T;
} }
} }
@ -184,7 +217,7 @@ export class DataStoreService {
* @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.get(User, [1,2,3,4,5])
*/ */
public getMany<T extends BaseModel>(collectionType: ModelConstructor | string, ids: ModelId[]): T[] { public getMany<T extends BaseModel>(collectionType: ModelConstructor | string, ids: number[]): T[] {
const collectionString = this.getCollectionString(collectionType); const collectionString = this.getCollectionString(collectionType);
const collection: ModelCollection = this.modelStore[collectionString]; const collection: ModelCollection = this.modelStore[collectionString];
@ -196,7 +229,7 @@ export class DataStoreService {
return collection[id]; return collection[id];
}) })
.filter(model => !!model); // remove non valid models. .filter(model => !!model); // remove non valid models.
return models; return models as T[];
} }
/** /**
@ -257,7 +290,7 @@ export class DataStoreService {
} }
this.JsonStore[collectionString][model.id] = JSON.stringify(model); this.JsonStore[collectionString][model.id] = JSON.stringify(model);
// if (model.changeId > maxChangeId) {maxChangeId = model.maxChangeId;} // if (model.changeId > maxChangeId) {maxChangeId = model.maxChangeId;}
this.setObservable(model); this.changedSubject.next(model);
}); });
this.storeToCache(maxChangeId); this.storeToCache(maxChangeId);
} }
@ -268,7 +301,7 @@ export class DataStoreService {
* @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)
*/ */
public remove(collectionType, ...ids: ModelId[]): void { public remove(collectionType, ...ids: number[]): void {
let collectionString: string; let collectionString: string;
if (typeof collectionType === 'string') { if (typeof collectionType === 'string') {
collectionString = collectionType; collectionString = collectionType;
@ -287,6 +320,10 @@ export class DataStoreService {
if (this.JsonStore[collectionString]) { if (this.JsonStore[collectionString]) {
delete this.JsonStore[collectionString][id]; delete this.JsonStore[collectionString][id];
} }
this.deletedSubject.next({
collection: collectionString,
id: id
});
}); });
this.storeToCache(maxChangeId); this.storeToCache(maxChangeId);
} }
@ -303,22 +340,6 @@ export class DataStoreService {
} }
} }
/**
* Observe the dataStore for changes.
* @return an observable behaviorSubject
*/
public getObservable(): Observable<any> {
return this.dataStoreSubject.asObservable();
}
/**
* Informs the observers for changes
* @param value the change that have been made
*/
private setObservable(value): void {
this.dataStoreSubject.next(value);
}
/** /**
* Prints the whole dataStore * Prints the whole dataStore
* @deprecated Shouldn't be used, will be removed later * @deprecated Shouldn't be used, will be removed later

View File

@ -83,7 +83,7 @@ export class OperatorService extends OpenSlidesComponent {
* permissions if the user or groups changes. * permissions if the user or groups changes.
*/ */
public setupSubscription() { public setupSubscription() {
this.DS.getObservable().subscribe(newModel => { this.DS.changeObservable.subscribe(newModel => {
if (this._user) { if (this._user) {
if (newModel instanceof Group) { if (newModel instanceof Group) {
this.updatePermissions(); this.updatePermissions();

View File

@ -2,11 +2,6 @@ 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';
/**
* Define that an ID might be a number or a string.
*/
export type ModelId = number | string;
export interface ModelConstructor { export interface ModelConstructor {
new (...args: any[]): BaseModel; new (...args: any[]): BaseModel;
} }
@ -34,7 +29,7 @@ export abstract class BaseModel extends OpenSlidesComponent implements Deseriali
/** /**
* force children of BaseModel to have an id * force children of BaseModel to have an id
*/ */
public abstract id: ModelId; public abstract id: number;
/** /**
* constructor that calls super from parent class * constructor that calls super from parent class

View File

@ -81,7 +81,7 @@ export class Motion extends BaseModel {
}); });
// observe for new models // observe for new models
this.DS.getObservable().subscribe(newModel => { this.DS.changeObservable.subscribe(newModel => {
if (newModel instanceof Workflow) { if (newModel instanceof Workflow) {
if (newModel.isStateContained(this.state_id)) { if (newModel.isStateContained(this.state_id)) {
this.workflow = newModel as Workflow; this.workflow = newModel as Workflow;

View File

@ -59,7 +59,7 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
// Observe DataStore for motions. Initially, executes once for every motion. // Observe DataStore for motions. Initially, executes once for every motion.
// 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.getObservable().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>(Category);
this.dataSource.data = this.categoryArray; this.dataSource.data = this.categoryArray;

View File

@ -91,7 +91,7 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
this.motion = this.DS.get(Motion, params.id) as Motion; this.motion = this.DS.get(Motion, params.id) as Motion;
// 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.getObservable().subscribe(newModel => { this.DS.changeObservable.subscribe(newModel => {
if (newModel instanceof Motion) { if (newModel instanceof Motion) {
if (newModel.id === +params.id) { if (newModel.id === +params.id) {
this.motion = newModel as Motion; this.motion = newModel as Motion;

View File

@ -101,7 +101,7 @@ export class MotionListComponent extends BaseComponent implements OnInit {
// Observe DataStore for motions. Initially, executes once for every motion. // Observe DataStore for motions. Initially, executes once for every motion.
// 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.getObservable().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>(Motion);
this.dataSource.data = this.motionArray; this.dataSource.data = this.motionArray;

View File

@ -64,7 +64,7 @@ export class StartComponent extends BaseComponent implements OnInit {
} }
// observe title and text in DS // observe title and text in DS
this.DS.getObservable().subscribe(newModel => { this.DS.changeObservable.subscribe(newModel => {
if (newModel instanceof Config) { if (newModel instanceof Config) {
if (newModel.key === 'general_event_welcome_title') { if (newModel.key === 'general_event_welcome_title') {
this.welcomeTitle = newModel.value as string; this.welcomeTitle = newModel.value as string;