mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-09 02:54:13 +00:00
Switched to angular 5's built-in transfer state api
This commit is contained in:
@@ -23,9 +23,6 @@ import { AppComponent } from './app.component';
|
|||||||
import { HostWindowState } from './shared/host-window.reducer';
|
import { HostWindowState } from './shared/host-window.reducer';
|
||||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||||
|
|
||||||
import { BrowserTransferStateModule } from '../modules/transfer-state/browser-transfer-state.module';
|
|
||||||
import { BrowserTransferStoreModule } from '../modules/transfer-store/browser-transfer-store.module';
|
|
||||||
|
|
||||||
import { MetadataService } from './core/metadata/metadata.service';
|
import { MetadataService } from './core/metadata/metadata.service';
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, ENV_CONFIG } from '../config';
|
import { GLOBAL_CONFIG, ENV_CONFIG } from '../config';
|
||||||
@@ -53,8 +50,6 @@ describe('App component', () => {
|
|||||||
useClass: MockTranslateLoader
|
useClass: MockTranslateLoader
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
BrowserTransferStateModule,
|
|
||||||
BrowserTransferStoreModule
|
|
||||||
],
|
],
|
||||||
declarations: [AppComponent], // declare the test component
|
declarations: [AppComponent], // declare the test component
|
||||||
providers: [
|
providers: [
|
||||||
|
@@ -13,7 +13,6 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
|
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../config';
|
import { GLOBAL_CONFIG, GlobalConfig } from '../config';
|
||||||
|
|
||||||
import { TransferState } from '../modules/transfer-state/transfer-state';
|
|
||||||
import { MetadataService } from './core/metadata/metadata.service';
|
import { MetadataService } from './core/metadata/metadata.service';
|
||||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||||
import { HostWindowState } from './shared/host-window.reducer';
|
import { HostWindowState } from './shared/host-window.reducer';
|
||||||
@@ -32,7 +31,6 @@ export class AppComponent implements OnInit {
|
|||||||
@Inject(GLOBAL_CONFIG) public config: GlobalConfig,
|
@Inject(GLOBAL_CONFIG) public config: GlobalConfig,
|
||||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private cache: TransferState,
|
|
||||||
private store: Store<HostWindowState>,
|
private store: Store<HostWindowState>,
|
||||||
private metadata: MetadataService
|
private metadata: MetadataService
|
||||||
) {
|
) {
|
||||||
@@ -48,16 +46,6 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked() {
|
|
||||||
this.syncCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
syncCache() {
|
|
||||||
this.store.take(1).subscribe((state: HostWindowState) => {
|
|
||||||
this.cache.set('state', state);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const env: string = this.config.production ? 'Production' : 'Development';
|
const env: string = this.config.production ? 'Production' : 'Development';
|
||||||
const color: string = this.config.production ? 'red' : 'green';
|
const color: string = this.config.production ? 'red' : 'green';
|
||||||
|
@@ -1,31 +1,32 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { APP_BASE_HREF, CommonModule } from '@angular/common';
|
||||||
import { CommonModule, APP_BASE_HREF } from '@angular/common';
|
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
import { EffectsModule } from '@ngrx/effects';
|
import { BrowserTransferStateModule } from '@angular/platform-browser';
|
||||||
import { StoreModule, MetaReducer, META_REDUCERS } from '@ngrx/store';
|
|
||||||
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
|
||||||
import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store';
|
|
||||||
|
|
||||||
import { storeFreeze } from 'ngrx-store-freeze';
|
|
||||||
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
import { appEffects } from './app.effects';
|
import { EffectsModule } from '@ngrx/effects';
|
||||||
import { appReducers, AppState } from './app.reducer';
|
import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store';
|
||||||
import { appMetaReducers, debugMetaReducers } from './app.metareducers';
|
import { META_REDUCERS, MetaReducer, StoreModule } from '@ngrx/store';
|
||||||
|
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
||||||
|
|
||||||
import { CoreModule } from './core/core.module';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { storeFreeze } from 'ngrx-store-freeze';
|
||||||
|
|
||||||
|
import { ENV_CONFIG, GLOBAL_CONFIG, GlobalConfig } from '../config';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { HeaderComponent } from './header/header.component';
|
|
||||||
import { FooterComponent } from './footer/footer.component';
|
|
||||||
import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
|
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, ENV_CONFIG, GlobalConfig } from '../config';
|
import { appEffects } from './app.effects';
|
||||||
|
import { appMetaReducers, debugMetaReducers } from './app.metareducers';
|
||||||
|
import { appReducers, AppState } from './app.reducer';
|
||||||
|
|
||||||
|
import { CoreModule } from './core/core.module';
|
||||||
|
import { FooterComponent } from './footer/footer.component';
|
||||||
|
import { HeaderComponent } from './header/header.component';
|
||||||
|
import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
|
||||||
|
|
||||||
import { DSpaceRouterStateSerializer } from './shared/ngrx/dspace-router-state-serializer';
|
import { DSpaceRouterStateSerializer } from './shared/ngrx/dspace-router-state-serializer';
|
||||||
|
|
||||||
|
@@ -1,31 +1,31 @@
|
|||||||
import 'zone.js/dist/zone';
|
import 'zone.js/dist/zone';
|
||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
|
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
import { bootloader } from '@angularclass/bootloader';
|
import { bootloader } from '@angularclass/bootloader';
|
||||||
|
|
||||||
import { load as loadWebFont } from 'webfontloader';
|
import { load as loadWebFont } from 'webfontloader';
|
||||||
|
|
||||||
import { BrowserAppModule } from './modules/app/browser-app.module';
|
import { BrowserAppModule } from './modules/app/browser-app.module';
|
||||||
|
|
||||||
import { ENV_CONFIG } from './config';
|
import { ENV_CONFIG } from './config';
|
||||||
|
|
||||||
if (ENV_CONFIG.production) {
|
if (ENV_CONFIG.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
// Load fonts async
|
// Load fonts async
|
||||||
// https://github.com/typekit/webfontloader#configuration
|
// https://github.com/typekit/webfontloader#configuration
|
||||||
loadWebFont({
|
loadWebFont({
|
||||||
google: {
|
google: {
|
||||||
families: ['Droid Sans']
|
families: ['Droid Sans']
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return platformBrowserDynamic().bootstrapModule(BrowserAppModule);
|
return platformBrowserDynamic().bootstrapModule(BrowserAppModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// support async tag or hmr
|
// support async tag or hmr
|
||||||
bootloader(main);
|
document.addEventListener('DOMContentLoaded', () => bootloader(main));
|
||||||
|
@@ -1,30 +1,19 @@
|
|||||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { IdlePreload, IdlePreloadModule } from 'angular-idle-preload';
|
|
||||||
|
|
||||||
import { EffectsModule } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||||
|
|
||||||
|
import { IdlePreload, IdlePreloadModule } from 'angular-idle-preload';
|
||||||
|
|
||||||
import { AppComponent } from '../../app/app.component';
|
import { AppComponent } from '../../app/app.component';
|
||||||
|
|
||||||
import { AppModule } from '../../app/app.module';
|
import { AppModule } from '../../app/app.module';
|
||||||
import { BrowserTransferStateModule } from '../transfer-state/browser-transfer-state.module';
|
import { DSpaceBrowserTransferStateModule } from '../transfer-state/dspace-browser-transfer-state.module';
|
||||||
|
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
||||||
import { TransferState } from '../transfer-state/transfer-state';
|
|
||||||
import { BrowserTransferStoreEffects } from '../transfer-store/browser-transfer-store.effects';
|
|
||||||
import { BrowserTransferStoreModule } from '../transfer-store/browser-transfer-store.module';
|
|
||||||
|
|
||||||
export function init(cache: TransferState) {
|
|
||||||
return () => {
|
|
||||||
cache.initialize();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTranslateLoader(http: HttpClient) {
|
export function createTranslateLoader(http: HttpClient) {
|
||||||
return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
|
return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
|
||||||
@@ -34,7 +23,7 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule.withServerTransition({
|
BrowserModule.withServerTransition({
|
||||||
appId: 'ds-app-id'
|
appId: 'dspace-angular'
|
||||||
}),
|
}),
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
// forRoot ensures the providers are only created once
|
// forRoot ensures the providers are only created once
|
||||||
@@ -46,8 +35,7 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
IdlePreload
|
IdlePreload
|
||||||
}),
|
}),
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
BrowserTransferStateModule,
|
DSpaceBrowserTransferStateModule,
|
||||||
BrowserTransferStoreModule,
|
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
loader: {
|
loader: {
|
||||||
provide: TranslateLoader,
|
provide: TranslateLoader,
|
||||||
@@ -55,20 +43,13 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
deps: [HttpClient]
|
deps: [HttpClient]
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
EffectsModule.forRoot([BrowserTransferStoreEffects]),
|
|
||||||
AppModule
|
AppModule
|
||||||
],
|
],
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: APP_INITIALIZER,
|
|
||||||
multi: true,
|
|
||||||
useFactory: init,
|
|
||||||
deps: [
|
|
||||||
TransferState
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class BrowserAppModule {
|
export class BrowserAppModule {
|
||||||
|
constructor(
|
||||||
|
private transferState: DSpaceTransferState,
|
||||||
|
) {
|
||||||
|
this.transferState.transfer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,53 +1,20 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { ServerModule } from '@angular/platform-server';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import 'rxjs/add/operator/filter';
|
import 'rxjs/add/operator/filter';
|
||||||
import 'rxjs/add/operator/first';
|
import 'rxjs/add/operator/first';
|
||||||
|
|
||||||
import { ApplicationRef, NgModule, APP_BOOTSTRAP_LISTENER } from '@angular/core';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { ServerModule } from '@angular/platform-server';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
|
|
||||||
import { Request } from 'express';
|
|
||||||
|
|
||||||
import { REQUEST } from '@nguniversal/express-engine/tokens';
|
|
||||||
|
|
||||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { EffectsModule } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import { TranslateUniversalLoader } from '../translate-universal-loader';
|
|
||||||
|
|
||||||
import { ServerTransferStateModule } from '../transfer-state/server-transfer-state.module';
|
|
||||||
import { TransferState } from '../transfer-state/transfer-state';
|
|
||||||
|
|
||||||
import { ServerTransferStoreEffects } from '../transfer-store/server-transfer-store.effects';
|
|
||||||
import { ServerTransferStoreModule } from '../transfer-store/server-transfer-store.module';
|
|
||||||
|
|
||||||
import { AppState } from '../../app/app.reducer';
|
|
||||||
|
|
||||||
import { AppModule } from '../../app/app.module';
|
|
||||||
|
|
||||||
import { AppComponent } from '../../app/app.component';
|
import { AppComponent } from '../../app/app.component';
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../config';
|
import { AppModule } from '../../app/app.module';
|
||||||
|
import { DSpaceServerTransferStateModule } from '../transfer-state/dspace-server-transfer-state.module';
|
||||||
|
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
||||||
|
|
||||||
export function boot(cache: TransferState, appRef: ApplicationRef, store: Store<AppState>, request: Request, config: GlobalConfig) {
|
import { TranslateUniversalLoader } from '../translate-universal-loader';
|
||||||
// authentication mechanism goes here
|
|
||||||
return () => {
|
|
||||||
appRef.isStable.filter((stable: boolean) => stable).first().subscribe(() => {
|
|
||||||
// isStable == true doesn't guarantee that all dispatched actions have been
|
|
||||||
// processed yet. So in those cases the store snapshot wouldn't be complete
|
|
||||||
// and a rehydrate would leave the app in a broken state
|
|
||||||
//
|
|
||||||
// This setTimeout without delay schedules the cache.inject() to happen ASAP
|
|
||||||
// after everything that's already scheduled, and it solves that problem.
|
|
||||||
setTimeout(() => {
|
|
||||||
cache.inject();
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTranslateLoader() {
|
export function createTranslateLoader() {
|
||||||
return new TranslateUniversalLoader('dist/assets/i18n/', '.json');
|
return new TranslateUniversalLoader('dist/assets/i18n/', '.json');
|
||||||
@@ -57,14 +24,13 @@ export function createTranslateLoader() {
|
|||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule.withServerTransition({
|
BrowserModule.withServerTransition({
|
||||||
appId: 'ds-app-id'
|
appId: 'dspace-angular'
|
||||||
}),
|
}),
|
||||||
RouterModule.forRoot([], {
|
RouterModule.forRoot([], {
|
||||||
useHash: false
|
useHash: false
|
||||||
}),
|
}),
|
||||||
NoopAnimationsModule,
|
NoopAnimationsModule,
|
||||||
ServerTransferStateModule,
|
DSpaceServerTransferStateModule,
|
||||||
ServerTransferStoreModule,
|
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
loader: {
|
loader: {
|
||||||
provide: TranslateLoader,
|
provide: TranslateLoader,
|
||||||
@@ -72,25 +38,16 @@ export function createTranslateLoader() {
|
|||||||
deps: []
|
deps: []
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
EffectsModule.forRoot([ServerTransferStoreEffects]),
|
|
||||||
ServerModule,
|
ServerModule,
|
||||||
AppModule
|
AppModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
|
||||||
provide: APP_BOOTSTRAP_LISTENER,
|
|
||||||
multi: true,
|
|
||||||
useFactory: boot,
|
|
||||||
deps: [
|
|
||||||
TransferState,
|
|
||||||
ApplicationRef,
|
|
||||||
Store,
|
|
||||||
REQUEST,
|
|
||||||
GLOBAL_CONFIG
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ServerAppModule {
|
export class ServerAppModule {
|
||||||
|
constructor(
|
||||||
|
private transferState: DSpaceTransferState,
|
||||||
|
) {
|
||||||
|
this.transferState.transfer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserTransferState } from './browser-transfer-state';
|
|
||||||
import { TransferState } from './transfer-state';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [
|
|
||||||
{ provide: TransferState, useClass: BrowserTransferState }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class BrowserTransferStateModule {
|
|
||||||
|
|
||||||
}
|
|
@@ -1,47 +0,0 @@
|
|||||||
import { Inject, Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
import { Action, Store } from '@ngrx/store';
|
|
||||||
|
|
||||||
import { TransferState } from './transfer-state';
|
|
||||||
|
|
||||||
import { StoreAction, StoreActionTypes } from '../../app/store.actions';
|
|
||||||
import { AppState } from '../../app/app.reducer';
|
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../config';
|
|
||||||
import { RouterNavigationAction } from '@ngrx/router-store';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class BrowserTransferState extends TransferState {
|
|
||||||
|
|
||||||
constructor(private store: Store<AppState>, @Inject(GLOBAL_CONFIG) private config: GlobalConfig) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
// tslint:disable-next-line:no-string-literal
|
|
||||||
const cache: any = window['TRANSFER_STATE'] || {};
|
|
||||||
Object.keys(cache).forEach((key: string) => {
|
|
||||||
if (key !== 'actions') {
|
|
||||||
this.set(key, cache[key]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (this.config.prerenderStrategy === 'replay') {
|
|
||||||
if (cache.actions !== undefined) {
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.info('Replay:', (cache.actions !== undefined && cache.actions !== null) ? cache.actions : []);
|
|
||||||
}
|
|
||||||
this.store.dispatch(new StoreAction(StoreActionTypes.REPLAY, cache.actions));
|
|
||||||
} else {
|
|
||||||
console.info('No actions occured during prerender.');
|
|
||||||
}
|
|
||||||
} else if (this.config.prerenderStrategy === 'rehydrate') {
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.info('Rehydrate:', (cache.state !== undefined && cache.state !== null) ? cache.state : []);
|
|
||||||
}
|
|
||||||
this.store.dispatch(new StoreAction(StoreActionTypes.REHYDRATE, cache.state));
|
|
||||||
} else {
|
|
||||||
console.warn([this.config.prerenderStrategy, 'is not a valid prerender strategy!'].join(' '));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -0,0 +1,16 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserTransferStateModule } from '@angular/platform-browser';
|
||||||
|
import { DSpaceBrowserTransferState } from './dspace-browser-transfer-state.service';
|
||||||
|
import { DSpaceTransferState } from './dspace-transfer-state.service';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
BrowserTransferStateModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: DSpaceTransferState, useClass: DSpaceBrowserTransferState }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class DSpaceBrowserTransferStateModule {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { StoreAction, StoreActionTypes } from '../../app/store.actions';
|
||||||
|
import { DSpaceTransferState } from './dspace-transfer-state.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DSpaceBrowserTransferState extends DSpaceTransferState {
|
||||||
|
transfer() {
|
||||||
|
const state = this.transferState.get<any>(DSpaceTransferState.NGRX_STATE, null);
|
||||||
|
this.transferState.remove(DSpaceTransferState.NGRX_STATE);
|
||||||
|
this.store.dispatch(new StoreAction(StoreActionTypes.REHYDRATE, state));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,16 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { ServerTransferStateModule } from '@angular/platform-server';
|
||||||
|
import { DSpaceServerTransferState } from './dspace-server-transfer-state.service';
|
||||||
|
import { DSpaceTransferState } from './dspace-transfer-state.service';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
ServerTransferStateModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: DSpaceTransferState, useClass: DSpaceServerTransferState }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class DSpaceServerTransferStateModule {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,16 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { DSpaceTransferState } from './dspace-transfer-state.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DSpaceServerTransferState extends DSpaceTransferState {
|
||||||
|
transfer() {
|
||||||
|
this.transferState.onSerialize(DSpaceTransferState.NGRX_STATE, () => {
|
||||||
|
let state;
|
||||||
|
this.store.take(1).subscribe((saveState: any) => {
|
||||||
|
state = saveState;
|
||||||
|
});
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
18
src/modules/transfer-state/dspace-transfer-state.service.ts
Normal file
18
src/modules/transfer-state/dspace-transfer-state.service.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { makeStateKey, TransferState } from '@angular/platform-browser';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { AppState } from '../../app/app.reducer';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export abstract class DSpaceTransferState {
|
||||||
|
|
||||||
|
protected static NGRX_STATE = makeStateKey('NGRX_STATE');
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected transferState: TransferState,
|
||||||
|
protected store: Store<AppState>
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract transfer(): void
|
||||||
|
}
|
@@ -1,12 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { ServerTransferState } from './server-transfer-state';
|
|
||||||
import { TransferState } from './transfer-state';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [
|
|
||||||
{ provide: TransferState, useClass: ServerTransferState }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ServerTransferStateModule {
|
|
||||||
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
import { Inject, Injectable, RendererFactory2, ViewEncapsulation } from '@angular/core';
|
|
||||||
|
|
||||||
import { INITIAL_CONFIG, PlatformState } from '@angular/platform-server';
|
|
||||||
|
|
||||||
import { TransferState } from './transfer-state';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ServerTransferState extends TransferState {
|
|
||||||
|
|
||||||
constructor(private state: PlatformState, private rendererFactory: RendererFactory2) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
inject() {
|
|
||||||
try {
|
|
||||||
const document: any = this.state.getDocument();
|
|
||||||
const transferStateString = JSON.stringify(this.toJson());
|
|
||||||
const renderer = this.rendererFactory.createRenderer(document, {
|
|
||||||
id: '-1',
|
|
||||||
encapsulation: ViewEncapsulation.None,
|
|
||||||
styles: [],
|
|
||||||
data: {}
|
|
||||||
});
|
|
||||||
const head = document.children[1].children[0];
|
|
||||||
if (head.name !== 'head') {
|
|
||||||
throw new Error('Please have <head> as the first element in your document');
|
|
||||||
}
|
|
||||||
const script = renderer.createElement('script');
|
|
||||||
renderer.setValue(script, `window['TRANSFER_STATE'] = ${transferStateString}`);
|
|
||||||
renderer.appendChild(head, script);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,40 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
import { Action } from '@ngrx/store';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class TransferState {
|
|
||||||
|
|
||||||
protected map = new Map<string, any>();
|
|
||||||
|
|
||||||
keys() {
|
|
||||||
return this.map.keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
get(key: string): any {
|
|
||||||
return this.map.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(key: string, value: any): Map<string, any> {
|
|
||||||
return this.map.set(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): any {
|
|
||||||
const json: any = {};
|
|
||||||
Array.from(this.keys())
|
|
||||||
.forEach((key: string) => {
|
|
||||||
json[key] = this.get(key);
|
|
||||||
});
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize(): void {
|
|
||||||
console.log('Initialize does nothing!');
|
|
||||||
}
|
|
||||||
|
|
||||||
inject(): void {
|
|
||||||
console.log('Inject does nothing!');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
import { Inject, Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
import { Action } from '@ngrx/store';
|
|
||||||
import { Effect, Actions } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
|
|
||||||
import { types } from '../../app/shared/ngrx/type';
|
|
||||||
|
|
||||||
import { TransferStoreEffects } from './transfer-store.effects';
|
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../config';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class BrowserTransferStoreEffects extends TransferStoreEffects {
|
|
||||||
|
|
||||||
@Effect({ dispatch: false }) log = this.actions.ofType(...types()).switchMap((action: Action) => {
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.info(action);
|
|
||||||
}
|
|
||||||
return Observable.of({});
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(private actions: Actions, @Inject(GLOBAL_CONFIG) public config: GlobalConfig) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserTransferStoreEffects } from './browser-transfer-store.effects';
|
|
||||||
import { TransferStoreEffects } from './transfer-store.effects';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [
|
|
||||||
{ provide: TransferStoreEffects, useClass: BrowserTransferStoreEffects }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class BrowserTransferStoreModule {
|
|
||||||
|
|
||||||
}
|
|
@@ -1,36 +0,0 @@
|
|||||||
import { Inject, Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
import { Action } from '@ngrx/store';
|
|
||||||
import { Effect, Actions } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
|
|
||||||
import { types } from '../../app/shared/ngrx/type';
|
|
||||||
|
|
||||||
import { TransferStoreEffects } from './transfer-store.effects';
|
|
||||||
|
|
||||||
import { TransferState } from '../transfer-state/transfer-state';
|
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../config';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ServerTransferStoreEffects extends TransferStoreEffects {
|
|
||||||
|
|
||||||
@Effect({ dispatch: false }) track = this.actions.ofType(...types()).switchMap((action: Action) => {
|
|
||||||
this.cacheAction(action);
|
|
||||||
return Observable.of({});
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(private actions: Actions, private cache: TransferState, @Inject(GLOBAL_CONFIG) public config: GlobalConfig) {
|
|
||||||
super();
|
|
||||||
this.cache.set('actions', new Array<Action>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private cacheAction(action: Action): void {
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.info('Cache:', action);
|
|
||||||
}
|
|
||||||
this.cache.get('actions').push(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { ServerTransferStoreEffects } from './server-transfer-store.effects';
|
|
||||||
import { TransferStoreEffects } from './transfer-store.effects';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [
|
|
||||||
{ provide: TransferStoreEffects, useClass: ServerTransferStoreEffects }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ServerTransferStoreModule {
|
|
||||||
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
export abstract class TransferStoreEffects {
|
|
||||||
|
|
||||||
}
|
|
Reference in New Issue
Block a user