Skip to content

Instantly share code, notes, and snippets.

@Hotell
Last active June 26, 2018 12:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Hotell/123bd9d11f9f1ce777208b805b459683 to your computer and use it in GitHub Desktop.
Save Hotell/123bd9d11f9f1ce777208b805b459683 to your computer and use it in GitHub Desktop.
ngMetadata 2.x - with @ngrx/store
import { Component } from 'ng-metadata/core';
@Component({
selector: 'my-app',
template: '<h1>My First Angular 1 App <small>with ng-metadata!</small></h1>'
})
export class AppComponent { }
export { AppComponent } from './app.component';
import { bootstrap } from 'ng-metadata/platform-browser-dynamic';
import { AppComponent } from './index';
bootstrap( AppComponent );
/**
* Import @ngrx/store providers
*/
import { Reducer } from '@ngrx/store'
import { Dispatcher } from '@ngrx/store'
import { Store } from '@ngrx/store'
import { State } from '@ngrx/store'
import { combineReducers } from '@ngrx/store'
/**
* Create annotated versions of the providers so that ng-metadata
* can register them against our ng1 app
*/
import { Injectable, OpaqueToken } from 'ng-metadata/core'
@Injectable()
class Ng1Dispatcher extends Dispatcher {}
@Injectable()
class Ng1Store<T> extends Store<T> {}
@Injectable()
class Ng1State<T> extends State<T> {}
@Injectable()
class Ng1Reducer extends Reducer {}
/**
* ng-metadata doesn't currently support objects created via `new String()`,
* so create an alternative INITIAL_REDUCER and INITIAL_STATE using OpaqueToken
*/
export const INITIAL_REDUCER = new OpaqueToken('Token ngrx/store/reducer')
export const INITIAL_STATE = new OpaqueToken('Token ngrx/store/initial-state')
/**
* Replicate the structure of the contents of ng2.ts from @ngrx/store,
* but using the annotated dependencies
*/
const dispatcherProvider = {
provide: Ng1Dispatcher,
useFactory() {
return new Dispatcher()
}
}
const storeProvider = {
provide: Ng1Store,
deps: [Ng1Dispatcher, Ng1Reducer, Ng1State, INITIAL_STATE],
useFactory(dispatcher: Dispatcher, reducer: Reducer, state$: State<any>, initialState: any) {
return new Store<any>(dispatcher, reducer, state$, initialState)
}
}
const stateProvider = {
provide: Ng1State,
deps: [INITIAL_STATE, Ng1Dispatcher, Ng1Reducer],
useFactory(initialState: any, dispatcher: Dispatcher, reducer: Reducer) {
return new State(initialState, dispatcher, reducer)
}
}
const reducerProvider = {
provide: Ng1Reducer,
deps: [Ng1Dispatcher, INITIAL_REDUCER],
useFactory(dispatcher: Dispatcher, reducer: any) {
return new Reducer(dispatcher, reducer)
}
}
export function provideStore(reducer: any, initialState?: any): any[] {
return [
{
provide: INITIAL_REDUCER,
useFactory() {
if (typeof reducer === 'function') {
return reducer
}
return combineReducers(reducer)
}
},
{
provide: INITIAL_STATE,
deps: [INITIAL_REDUCER],
useFactory(reducer: Function) {
if (initialState === undefined) {
return reducer(undefined, { type: Dispatcher.INIT })
}
return initialState
}
},
dispatcherProvider,
storeProvider,
stateProvider,
reducerProvider,
]
}
/**
* Export the annotated store as `Store` so that we match
* the public interface of @ngrx/store
*/
export { Ng1Store as Store }
<!DOCTYPE html>
<html>
<head>
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="https://npmcdn.com/core-js/client/shim.min.js"></script>
<script src="https://npmcdn.com/reflect-metadata@0.1.3"></script>
<script src="https://npmcdn.com/systemjs@0.19.27/dist/system.src.js"></script>
<script src="https://code.angularjs.org/1.5.7/angular.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<link rel="stylesheet" href="style.css">
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
console.log('Hello World!');
/* todo: add styles */
System.config({
//use typescript for compilation
transpiler: 'ts',
typescriptOptions: {
tsconfig: true
},
meta: {
'typescript': {
"exports": "ts"
}
},
//map tells the System loader where to look for things
map: {
'app': './app',
'ng-metadata': 'https://npmcdn.com/ng-metadata',
'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6',
'@ngrx': 'https://npmcdn.com/@ngrx/store',
'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
'typescript': 'https://npmcdn.com/typescript@1.9.0-dev.20160409/lib/typescript.js',
},
//packages defines our app package
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
'ng-metadata': {
defaultExtension: 'js'
},
'rxjs': {
main: 'index.js',
defaultExtension: 'js'
},
'@ngrx/core': {
main: 'index.js',
format: 'cjs'
},
'@ngrx/store': {
main: 'index.js',
format: 'cjs'
}
}
});
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment