Created
August 7, 2018 12:19
-
-
Save KarolinaCzo/64111ff1a8b4ecdcac9cbeb1cad70629 to your computer and use it in GitHub Desktop.
'AppTranslationService' with Feature Module Store (dispatchers, actions, reducers) - Angular 2/6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1) In 'main-page-module.ts': | |
import { NgModule } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
// Import Bootstrap | |
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; | |
// Import components | |
import { MainPageComponent } from './main-page.component'; | |
import { NavbarComponent } from './components/navbar/navbar.component'; | |
import { FooterComponent } from './components/footer/footer.component'; | |
import { JumbotronComponent } from './components/jumbotron/jumbotron.component'; | |
import { AdvertisementsComponent } from './components/advertisements/advertisements.component'; | |
import { RouterModule } from '@angular/router'; | |
// Translate | |
import { HttpClientModule, HttpClient } from '@angular/common/http'; | |
import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; | |
import { TranslateHttpLoader } from '@ngx-translate/http-loader'; | |
// Import translation service | |
import { AppTranslateService } from './translation.service'; | |
// Import for reducers to work | |
import { StoreModule, ActionReducerMap, Action } from '@ngrx/store'; | |
import { reducers, FEATURE_STORE_NAME } from './main-page.reducers'; | |
// Import dispatcher | |
import { MainPageDispatcher } from './main-page.dispatcher'; | |
// AoT requires an exported function for factories | |
export function HttpLoaderFactory(http: HttpClient) { | |
return new TranslateHttpLoader(http, '/assets/i18n/main-page/', '.json'); | |
} | |
@NgModule({ | |
imports: [ | |
CommonModule, | |
NgbModule.forRoot(), | |
RouterModule, | |
HttpClientModule, | |
TranslateModule.forRoot({ | |
loader: { | |
provide: TranslateLoader, | |
useFactory: HttpLoaderFactory, | |
deps: [HttpClient] | |
} | |
}), | |
// Define a feature module Store, give it a name and show where to look for reducers | |
// Remember about inports! | |
StoreModule.forFeature(FEATURE_STORE_NAME, reducers) | |
], | |
declarations: [ | |
MainPageComponent, | |
NavbarComponent, | |
FooterComponent, | |
JumbotronComponent, | |
AdvertisementsComponent | |
], | |
bootstrap: [MainPageComponent], | |
exports: [MainPageComponent], | |
// Add the AppTranslationService and MainPageDispatcher to providers | |
providers: [AppTranslateService, MainPageDispatcher] | |
}) | |
export class MainPageModule {} | |
2) In 'navbar.component.ts': | |
import { Component, OnInit, HostListener } from '@angular/core'; | |
// Import translate service | |
import { AppTranslateService } from '../../translation.service'; | |
// Import Store | |
import { Store } from '@ngrx/store'; | |
// Import dispatcher | |
import { MainPageDispatcher } from '../../main-page.dispatcher'; | |
// Import State from reducers | |
import { MainPageState, getLanguage } from '../../main-page.reducers'; | |
@Component({ | |
selector: 'app-navbar', | |
templateUrl: './navbar.component.html', | |
styleUrls: ['./navbar.component.scss'] | |
}) | |
export class NavbarComponent { | |
constructor( | |
private translateService: AppTranslateService, | |
private store: Store<MainPageState>, // Pass the component state | |
private dispatcher: MainPageDispatcher | |
) {} | |
// Listen to clicks on language icons | |
onLanguageChange(language: string) { | |
this.dispatcher.changeLanguage(language); | |
} | |
// Listen to 'window:scroll' event for window level scrolling. | |
@HostListener('window:scroll', ['$event']) | |
onWindowScroll($event: any) { | |
const navbar = document.getElementById('navbar'); | |
// Check if the page offset is grater than 0 and if 'navbar' isn't 'null'. | |
if (window.pageYOffset > 0 && navbar) { | |
// Stick the 'navbar' to the top of the page. | |
navbar.style.top = '0'; | |
} | |
} | |
} | |
3) In 'main-page.dispatcher.ts': | |
// Import store | |
import { Store } from '@ngrx/store'; | |
// Import State from reducers | |
import { MainPageState } from './main-page.reducers'; | |
// Import Injectable | |
import { Injectable } from '@angular/core'; | |
// Import Actions from actions | |
import { ChangeLanguageAction } from './main-page.actions'; | |
@Injectable() | |
export class MainPageDispatcher { | |
constructor(private store: Store<MainPageState>) {} | |
changeLanguage(language: string) { | |
this.store.dispatch(new ChangeLanguageAction(language)); | |
} | |
} | |
4) In 'main-page.actions.ts': | |
import { Action } from '@ngrx/store'; | |
// Create variables to be sure that the names of actions are always the same | |
export const LANGUAGE_CHANGE = 'LANGUAGE_CHANGE'; | |
// Create actions | |
export class ChangeLanguageAction implements Action { | |
readonly type = LANGUAGE_CHANGE; | |
constructor(public payload: string) {} | |
} | |
export type MainPageActions = ChangeLanguageAction; | |
5) In 'main-page.reducers.ts': | |
// Import for reducers to work | |
import { | |
StoreModule, | |
ActionReducerMap, | |
Action, | |
ActionReducer, | |
createFeatureSelector, | |
createSelector | |
} from '@ngrx/store'; | |
// Import actions | |
import { LANGUAGE_CHANGE, ChangeLanguageAction } from './main-page.actions'; | |
// Define the feature module name as const to avoid mistakes | |
export const FEATURE_STORE_NAME = 'main-page'; | |
// Define a feature state | |
export interface MainPageState { | |
language: string; | |
} | |
// Create a feature state selector | |
export const selectFeature = createFeatureSelector<MainPageState>( | |
FEATURE_STORE_NAME | |
); | |
// Create a selector for the counter (to update it) | |
export const getLanguage = createSelector( | |
selectFeature, | |
state => state.language | |
); | |
// Create a reducer | |
export const MainPageReducer: ActionReducer<string, ChangeLanguageAction> = ( | |
state: string = 'de', | |
action: ChangeLanguageAction | |
) => { | |
switch (action.type) { | |
case LANGUAGE_CHANGE: | |
state = action.payload; | |
return state; | |
default: | |
return state; | |
} | |
}; | |
// Update the language with the curent state | |
export const reducers: ActionReducerMap<MainPageState, ChangeLanguageAction> = { | |
language: MainPageReducer | |
}; | |
6) In 'translation.service.ts': | |
import { Injectable } from '@angular/core'; | |
import { HttpClient } from '@angular/common/http'; | |
// Import translate service | |
import { TranslateService } from '@ngx-translate/core'; | |
// Import Observable | |
import { Observable } from 'rxjs'; | |
// Import reducers | |
import { Store } from '@ngrx/store'; | |
import { MainPageState, getLanguage } from './main-page.reducers'; | |
@Injectable() | |
export class AppTranslateService { | |
// Create an Observable to listen for language change | |
private language$: Observable<string>; | |
constructor( | |
private translate: TranslateService, | |
private store: Store<MainPageState> | |
) { | |
translate.addLangs(['de', 'en']); | |
translate.setDefaultLang('de'); | |
this.language$ = this.store.select(getLanguage); | |
this.language$.subscribe(value => { | |
this.translate.use(value); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment