reimplemented header navbar toggle using redux

This commit is contained in:
Art Lowel
2016-12-12 14:57:07 +01:00
parent 9aa74b863e
commit 69f8d9855a
8 changed files with 123 additions and 13 deletions

View File

@@ -62,6 +62,10 @@
"@angularclass/bootloader": "1.0.1",
"@angularclass/idle-preload": "1.0.4",
"@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.14",
"@ngrx/core": "^1.2.0",
"@ngrx/effects": "^2.0.0",
"@ngrx/store": "^2.2.1",
"@ngrx/store-devtools": "^3.2.2",
"angular2-express-engine": "2.1.0-rc.1",
"angular2-platform-node": "2.1.0-rc.1",
"angular2-universal": "2.1.0-rc.1",

5
src/app/app.actions.ts Normal file
View File

@@ -0,0 +1,5 @@
import { HeaderActions } from "./header/header.actions";
export default [
HeaderActions
];

View File

@@ -7,6 +7,12 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { StoreModule } from "@ngrx/store";
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
import reducers from './app.reducers'
import actions from './app.actions'
@NgModule({
declarations: [
@@ -16,7 +22,29 @@ import { HeaderComponent } from './header/header.component';
imports: [
SharedModule,
HomeModule,
AppRoutingModule
AppRoutingModule,
/**
* StoreModule.provideStore is imported once in the root module, accepting a reducer
* function or object map of reducer functions. If passed an object of
* reducers, combineReducers will be run creating your application
* meta-reducer. This returns all providers for an @ngrx/store
* based application.
*/
StoreModule.provideStore(reducers),
/**
* Store devtools instrument the store retaining past versions of state
* and recalculating new states. This enables powerful time-travel
* debugging.
*
* To use the debugger, install the Redux Devtools extension for either
* Chrome or Firefox
*
* See: https://github.com/zalmoxisus/redux-devtools-extension
*/
StoreDevtoolsModule.instrumentOnlyWithExtension(),
],
providers: [
actions
]
})
export class AppModule {

5
src/app/app.reducers.ts Normal file
View File

@@ -0,0 +1,5 @@
import { headerReducer } from './header/header.reducer';
export default {
headerReducer
}

View File

@@ -0,0 +1,26 @@
import { Injectable } from "@angular/core";
import { Action } from "@ngrx/store";
@Injectable()
export class HeaderActions {
static COLLAPSE = 'dspace/header/COLLAPSE';
collapse(): Action {
return {
type: HeaderActions.COLLAPSE
}
}
static EXPAND = 'dspace/header/EXPAND';
expand(): Action {
return {
type: HeaderActions.EXPAND
}
}
static TOGGLE = 'dspace/header/TOGGLE';
toggle(): Action {
return {
type: HeaderActions.TOGGLE
}
}
}

View File

@@ -3,11 +3,11 @@
<button class="navbar-toggler hidden-sm-up" type="button" (click)="toggle()" aria-controls="collapsingNav" aria-expanded="false" aria-label="Toggle navigation">
<i class="fa fa-bars fa-fw" aria-hidden="true"></i>
</button>
<div [ngClass]="{'clearfix': !isNavBarCollaped()}">
<div [ngClass]="{'clearfix': !(isNavBarCollapsed | async)}">
<a class="navbar-brand" routerLink="/home">
<!-- TODO: add logo here -->{{ 'title' | translate }}</a>
</div>
<div [ngbCollapse]="isNavBarCollaped()" class="collapse navbar-toggleable-xs" id="collapsingNav">
<div [ngbCollapse]="(isNavBarCollapsed | async)" class="collapse navbar-toggleable-xs" id="collapsingNav">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link" routerLink="/home" routerLinkActive="active"><i class="fa fa-home fa-fw" aria-hidden="true"></i> {{ 'nav.home' | translate }}<span class="sr-only">(current)</span></a>

View File

@@ -1,5 +1,9 @@
import { Component, OnInit, OnDestroy, HostListener } from "@angular/core";
import { Router, NavigationEnd, Event } from "@angular/router";
import { Store } from "@ngrx/store";
import { HeaderState } from "./header.reducer";
import { HeaderActions } from "./header.actions";
import { Observable } from "rxjs";
@Component({
selector: 'ds-header',
@@ -7,13 +11,14 @@ import { Router, NavigationEnd, Event } from "@angular/router";
templateUrl: 'header.component.html'
})
export class HeaderComponent implements OnDestroy, OnInit {
private navCollapsed: boolean;
private routerSubscription: any;
public isNavBarCollapsed: Observable<boolean>;
constructor(
private router: Router
private router: Router,
private actions: HeaderActions,
private store: Store<HeaderState>
) {
this.collapse();
}
ngOnInit(): void {
@@ -22,6 +27,8 @@ export class HeaderComponent implements OnDestroy, OnInit {
this.collapse();
}
});
this.isNavBarCollapsed = this.store.select('headerReducer')
.map(({ navCollapsed }: HeaderState) => navCollapsed);
}
ngOnDestroy(): void {
@@ -36,19 +43,15 @@ export class HeaderComponent implements OnDestroy, OnInit {
}
private collapse(): void {
this.navCollapsed = true;
this.store.dispatch(this.actions.collapse());
}
private expand(): void {
this.navCollapsed = false;
this.store.dispatch(this.actions.expand());
}
public toggle(): void {
this.navCollapsed ? this.expand() : this.collapse();
}
public isNavBarCollaped(): boolean {
return this.navCollapsed;
this.store.dispatch(this.actions.toggle());
}
}

View File

@@ -0,0 +1,39 @@
import { Action } from "@ngrx/store";
import { HeaderActions } from "./header.actions";
export interface HeaderState {
navCollapsed: boolean;
}
const initialState: HeaderState = {
navCollapsed: true
};
export const headerReducer = (state = initialState, action: Action): HeaderState => {
switch (action.type) {
case HeaderActions.COLLAPSE: {
return Object.assign({}, state, {
navCollapsed: true
});
}
case HeaderActions.EXPAND: {
return Object.assign({}, state, {
navCollapsed: false
});
}
case HeaderActions.TOGGLE: {
return Object.assign({}, state, {
navCollapsed: !state.navCollapsed
});
}
default: {
return state;
}
}
};