Add basic caching

This commit is contained in:
Michał Romaszkin 2020-06-14 21:21:04 +02:00
parent a45864ceae
commit b029d38145
10 changed files with 119 additions and 10 deletions

View File

@ -0,0 +1,39 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class GetDiscussionService {
private discussionObservableCache$: {
[id: string]: Observable<string>;
} = {};
private discussionCache$: {
[id: string]: string;
} = {};
constructor(private http: HttpClient) {}
getDiscussion(id: string): Observable<string> {
if (this.discussionCache$[id]) {
console.log('Cached');
return of(this.discussionCache$[id]);
} else {
console.log('Not cached');
this.discussionObservableCache$[id] = this.requestDiscussion(id);
return this.discussionObservableCache$[id];
}
}
private requestDiscussion(id: string): Observable<string> {
return this.http
.get<any>(`http://127.0.0.1:8000/discussions/${id}`)
.pipe(map((data) => this.mapData(id, data)));
}
private mapData(id: string, data: any) {
this.discussionCache$[id] = data;
return data;
}
}

View File

@ -1,10 +1,13 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { ForumData } from '../_interfaces/forumdata'; import { NbMenuItem } from '@nebular/theme';
@Injectable() @Injectable()
export class SharedDataService { export class SharedDataService {
private dataBS: BehaviorSubject<any> = new BehaviorSubject(null); private dataBS: BehaviorSubject<any> = new BehaviorSubject(null);
private discussionsBS: BehaviorSubject<NbMenuItem[]> = new BehaviorSubject(
[] as NbMenuItem[]
);
constructor() {} constructor() {}
@ -12,6 +15,14 @@ export class SharedDataService {
this.dataBS.next(value); this.dataBS.next(value);
} }
public setDiscussions(items: NbMenuItem[]) {
this.discussionsBS.next(items);
}
public getDiscussions(): Observable<NbMenuItem[]> {
return this.discussionsBS.asObservable();
}
public getData(): Observable<string> { public getData(): Observable<string> {
return this.dataBS.asObservable(); return this.dataBS.asObservable();
} }

View File

@ -32,7 +32,6 @@ export class DiscussionChooserComponent implements OnInit, OnDestroy {
public data: CustomForumData; public data: CustomForumData;
colors: Colors[] = ['primary', 'danger', 'info', 'success', 'warning']; colors: Colors[] = ['primary', 'danger', 'info', 'success', 'warning'];
private dataSub: Subscription; private dataSub: Subscription;
@Output() discussions = new EventEmitter<NbMenuItem[]>();
constructor(private sharedDataService: SharedDataService) {} constructor(private sharedDataService: SharedDataService) {}
@ -46,12 +45,12 @@ export class DiscussionChooserComponent implements OnInit, OnDestroy {
(element): NbMenuItem => { (element): NbMenuItem => {
return { return {
title: element.title, title: element.title,
link: '/view/discussion', link: `/view/forum/${element.id}`,
}; };
} }
); );
this.discussions.emit(fetchedDiscussions); this.sharedDataService.setDiscussions(fetchedDiscussions);
} }
}); });
} }

View File

@ -0,0 +1 @@
<div class="discussion-viewer"></div>

View File

@ -0,0 +1,33 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { GetDiscussionService } from '../../_services/get-discussion.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-discussion-viewer',
templateUrl: './discussion-viewer.component.html',
styleUrls: ['./discussion-viewer.component.scss'],
})
export class DiscussionViewerComponent implements OnInit {
data: any;
id: string;
paramSub: Subscription;
discussionSub: Subscription;
constructor(
private getDiscussionService: GetDiscussionService,
private router: ActivatedRoute
) {}
ngOnInit(): void {
this.paramSub = this.router.params.subscribe((params) => {
this.id = params.id;
this.discussionSub = this.getDiscussionService
.getDiscussion(this.id)
.subscribe((res) => {
console.log(res);
});
});
}
}

View File

@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule, Router } from '@angular/router'; import { Routes, RouterModule, Router } from '@angular/router';
import { MainViewComponent } from './main-view.component'; import { MainViewComponent } from './main-view.component';
import { DiscussionChooserComponent } from './discussion-chooser/discussion-chooser.component'; import { DiscussionChooserComponent } from './discussion-chooser/discussion-chooser.component';
import { DiscussionViewerComponent } from './discussion-viewer/discussion-viewer.component';
const routes: Routes = [ const routes: Routes = [
{ {
@ -12,6 +13,10 @@ const routes: Routes = [
path: 'discussions', path: 'discussions',
component: DiscussionChooserComponent, component: DiscussionChooserComponent,
}, },
{
path: 'forum/:id',
component: DiscussionViewerComponent,
},
{ {
path: '', path: '',
redirectTo: 'discussions', redirectTo: 'discussions',

View File

@ -20,6 +20,6 @@
<nb-menu [items]="items"></nb-menu> <nb-menu [items]="items"></nb-menu>
</nb-sidebar> </nb-sidebar>
<nb-layout-column> <nb-layout-column>
<router-outlet (activate)="onActivate($event)"></router-outlet> <router-outlet></router-outlet>
</nb-layout-column> </nb-layout-column>
</nb-layout> </nb-layout>

View File

@ -1,14 +1,21 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import {
Component,
AfterViewInit,
ChangeDetectionStrategy,
} from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { SharedDataService } from '../_services/shared-data.service';
import { NbSidebarService, NbMenuItem } from '@nebular/theme'; import { NbSidebarService, NbMenuItem } from '@nebular/theme';
@Component({ @Component({
selector: 'app-main-view', selector: 'app-main-view',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './main-view.component.html', templateUrl: './main-view.component.html',
styleUrls: ['./main-view.component.scss'], styleUrls: ['./main-view.component.scss'],
}) })
export class MainViewComponent { export class MainViewComponent implements AfterViewInit {
items: NbMenuItem[] = [ items: NbMenuItem[] = [
{ {
title: 'Dyskusje', title: 'Dyskusje',
@ -17,6 +24,7 @@ export class MainViewComponent {
]; ];
constructor( constructor(
private sidebarService: NbSidebarService, private sidebarService: NbSidebarService,
private sharedDataService: SharedDataService,
private router: Router private router: Router
) {} ) {}
@ -28,9 +36,15 @@ export class MainViewComponent {
this.router.navigate(['/']); this.router.navigate(['/']);
} }
onActivate(event: any) { ngAfterViewInit(): void {
event.discussions.subscribe((res: NbMenuItem[]) => { this.sharedDataService.getDiscussions().subscribe((res) => {
this.items[0].children = res; this.items[0].children = res;
}); });
} }
// onActivate(event: any) {
// event.discussions.subscribe((res: NbMenuItem[]) => {
// this.items[0].children = res;
// });
// }
} }

View File

@ -13,9 +13,15 @@ import {
NbCardModule, NbCardModule,
NbMenuModule, NbMenuModule,
} from '@nebular/theme'; } from '@nebular/theme';
import { DiscussionViewerComponent } from './discussion-viewer/discussion-viewer.component';
import { GetDiscussionService } from '../_services/get-discussion.service';
@NgModule({ @NgModule({
declarations: [MainViewComponent, DiscussionChooserComponent], declarations: [
MainViewComponent,
DiscussionChooserComponent,
DiscussionViewerComponent,
],
imports: [ imports: [
CommonModule, CommonModule,
MainViewRoutingModule, MainViewRoutingModule,
@ -26,5 +32,6 @@ import {
NbCardModule, NbCardModule,
NbMenuModule, NbMenuModule,
], ],
providers: [GetDiscussionService],
}) })
export class MainViewModule {} export class MainViewModule {}