Permalink
Browse files

Feature/reduce store example (#4)

* Files of ReduceStore example.

* `wwwroot` excluded in tsconfig.json to have single source of type definitions files.

* Node modules folder name fixed in .gitignore.

* `npm scripts` build command fixed in package.json.

* JSPM config updated to cache latest versions.

* Exclude changed in `tsconfig.production.json`.

* Naming changed in example's source files.

* Naming changed in `counter-container.tsx`.

* Example's README.md added.

* Links to documentation added.
  • Loading branch information...
DeividasBakanas authored and GiedriusGrabauskas committed Sep 11, 2017
1 parent bce373f commit 07ce20c997bbb1a1e341ea5bf962030766a7ba7f
View
@@ -168,6 +168,8 @@ class CounterReduceStoreClass extends ReduceStore<StoreState> {
export const CounterReduceStore = new CounterReduceStoreClass();
```
Full working example can be found in [`examples/reduce-store-example`](./examples/reduce-store-example).
### MapStore
[`MapStore`](#map-store) is a key-value store with a state of [Immutable.Map](https://facebook.github.io/immutable-js/docs/#/Map) that keeps key-value pairs of the same value type.
@@ -296,6 +298,8 @@ class ContactDataStoreClass extends DataStore {
export const ContactDataStore = new ContactDataStoreClass();
```
Full working example can be found in [`examples/data-store-example`](./examples/data-store-example).
## Container
To keep `Views` up to date with the latest data from stores we recommend you to use `flux/utils` [Container](https://facebook.github.io/flux/docs/flux-utils.html#container).
View
@@ -2,6 +2,6 @@
This directory contains examples of basic SimplrFlux functionality.
## [./data-store-example](./data-store-example) - Basic functionality of DataStore.
## [./data-store-example](./data-store-example) - Basic functionality of DataStore
## [./reduce-store-example](./reduce-store-example) - Basic functionality of ReduceStore
## [./map-store-example](./map-store-example) - Basic functionality of MapStore
@@ -1,7 +1,6 @@
# Example of DataStore
<!--- TODO: add link to DataStore documentation --->
Example of `DataStore`.
Example of [`DataStore`](../../README.md#datastore).
## Getting started
@@ -30,5 +29,4 @@ This example uses:
- [`systemjs/plugin-json`](https://github.com/systemjs/plugin-json) to load `JSON` files.
- [`path`](https://nodejs.org/api/path.html) polyfill that is supplied by [`JSPM`](http://jspm.io/) to handle paths to `JSON` files.
<!--- TODO: add link to SimplrFlux README --->
These dependencies are not necessary for `SimplrFlux`, it's just an example of its capabilities in action.
These dependencies are not necessary for [`SimplrFlux`](../../README.md), it's just an example of its capabilities in action.
@@ -0,0 +1,2 @@
node_modules
wwwroot
@@ -0,0 +1,28 @@
# Example of ReduceStore
Example of [`ReduceStore`](../../README.md#reducestore).
## Getting started
```sh
npm run setup
npm run start
```
Built example will be available on `http://localhost:4040`.
## Brief
This example contains [`counter-store.ts`](./src/app/counter/counter-store.ts) that stores data gathered from the user interface. Data in a store is updated according [`actions`](../../README.md#actions) from [`counter-actions.ts`](./src/app/counter/counter-actions.ts) and dispatched whenever [`action creators`](../../README.md#action-creators) from [`counter-actions-creators.ts`](./src/app/counter/counter-actions-creators.ts) are invoked.
All controls for user interactions and latest store data is rendered in [`counter-container.tsx`](./src/app/counter/counter-container.tsx).
## Dependencies
This example uses:
- [`SimplrGulp`](https://github.com/QuatroCode/simplr-gulp) to build a project.
- [`SystemJS`](https://github.com/systemjs/systemjs) to load modules.
These dependencies are not necessary for [`SimplrFlux`](../../README.md), it's just an example of its capabilities in action.
@@ -0,0 +1,36 @@
{
"Directories": {
"Source": "src",
"Build": "wwwroot",
"App": "app"
},
"TypeScriptConfig": {
"Development": "tsconfig.json",
"Production": "tsconfig.production.json"
},
"ServerConfig": {
"Ip": "127.0.0.1",
"Port": 4040,
"LiveReloadPort": 4004
},
"BundleConfig": {
"AppFile": "app.js",
"BuildFile": "app/build.js",
"Include": [
"css"
],
"Exclude": [
"core-js",
"flux",
"immutable",
"react",
"react-dom",
"simplr-flux",
"[simplr-flux/**/*]",
"path",
"js-base64"
]
},
"WebConfig": null,
"CfgVersion": 2.02
}
@@ -0,0 +1 @@
require("simplr-gulp");
@@ -0,0 +1,92 @@
{
"name": "reduce-store-example",
"version": "0.1.0",
"description": "Example of SimplrFlux ReduceStore.",
"private": true,
"scripts": {
"setup": "npm install && jspm install",
"build": "gulp Build",
"start": "gulp"
},
"devDependencies": {
"gulp": "gulpjs/gulp#4.0",
"jspm": "^0.17.0-beta.32",
"simplr-gulp": "^2.4.0",
"tslint": "^5.4.2",
"typescript": "^2.1.1"
},
"dependencies": {
"@types/core-js": "^0.9.34",
"@types/node": "^7.0.28",
"@types/react": "^15.0.28",
"@types/react-dom": "^15.5.0",
"@types/systemjs": "^0.19.32",
"@types/flux": "^3.1.0",
"simplr-flux": "^2.0.1"
},
"jspm": {
"name": "reduce-store-example",
"main": "app/app.js",
"configFiles": {
"jspm": "src/configs/jspm.config.js"
},
"directories": {
"packages": "wwwroot/libs",
"baseURL": "wwwroot"
},
"dependencies": {
"flux": "npm:flux@^3.1.0",
"react-dom": "npm:react-dom@^15.4.1",
"simplr-flux": "npm:simplr-flux@^2.0.1"
},
"devDependencies": {},
"peerDependencies": {
"assert": "npm:jspm-nodelibs-assert@^0.2.0",
"buffer": "npm:jspm-nodelibs-buffer@^0.2.0",
"child_process": "npm:jspm-nodelibs-child_process@^0.2.0",
"constants": "npm:jspm-nodelibs-constants@^0.2.0",
"crypto": "npm:jspm-nodelibs-crypto@^0.2.0",
"domain": "npm:jspm-nodelibs-domain@^0.2.0",
"events": "npm:jspm-nodelibs-events@^0.2.0",
"fs": "npm:jspm-nodelibs-fs@^0.2.0",
"http": "npm:jspm-nodelibs-http@^0.2.0",
"https": "npm:jspm-nodelibs-https@^0.2.0",
"immutable": "npm:immutable@^3.8.1",
"os": "npm:jspm-nodelibs-os@^0.2.0",
"path": "npm:jspm-nodelibs-path@^0.2.0",
"process": "npm:jspm-nodelibs-process@^0.2.0",
"react": "npm:react@^15.0.2",
"stream": "npm:jspm-nodelibs-stream@^0.2.0",
"string_decoder": "npm:jspm-nodelibs-string_decoder@^0.2.0",
"url": "npm:jspm-nodelibs-url@^0.2.0",
"util": "npm:jspm-nodelibs-util@^0.2.0",
"vm": "npm:jspm-nodelibs-vm@^0.2.0",
"zlib": "npm:jspm-nodelibs-zlib@^0.2.0"
},
"overrides": {
"npm:browserify-zlib@0.1.4": {
"dependencies": {
"readable-stream": "^2.0.2",
"pako": "~0.2.0"
},
"map": {
"_stream_transform": "readable-stream/transform"
}
},
"npm:inherits@2.0.3": {
"ignore": [
"test.js"
]
},
"npm:pbkdf2@3.0.12": {
"main": "browser.js"
},
"npm:safe-buffer@5.0.1": {
"browser": "index.js"
},
"npm:safe-buffer@5.1.0": {
"browser": "index.js"
}
}
}
}
@@ -0,0 +1,26 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import { CounterContainer } from "./counter/counter-container";
new class App {
constructor() {
this.startApp();
}
private startApp() {
let appRoot = document.getElementById("app-root");
if (appRoot != null) {
ReactDOM.render(<CounterContainer />, appRoot);
} else {
this.generateAppRootElement();
}
}
private generateAppRootElement() {
let newRoot = document.createElement("div");
newRoot.id = "app-root";
document.body.appendChild(newRoot);
this.startApp();
}
};
@@ -0,0 +1,25 @@
import { Dispatcher } from "simplr-flux";
import {
CountIncrementedAction,
CountDecrementedAction,
CountResetAction,
CountChangedAction
} from "./counter-actions";
export namespace CounterActionsCreators {
export function CountIncremented() {
Dispatcher.dispatch(new CountIncrementedAction);
}
export function CountDecremented() {
Dispatcher.dispatch(new CountDecrementedAction);
}
export function CountReset() {
Dispatcher.dispatch(new CountResetAction);
}
export function CountChanged(count: number) {
Dispatcher.dispatch(new CountChangedAction(count));
}
}
@@ -0,0 +1,15 @@
// actions with no data provided
export class CountIncrementedAction { }
export class CountDecrementedAction { }
export class CountResetAction { }
// action with additional data provided
export class CountChangedAction {
constructor(private count: number) {}
public get Count() {
return this.count;
}
}
@@ -0,0 +1,64 @@
import * as React from "react";
import { Container } from "flux/utils";
import { CounterReduceStore } from "./counter-store";
import { CounterActionsCreators } from "./counter-actions-creators";
interface State {
Count: number;
}
class CounterContainerClass extends React.Component<{}, State> {
static getStores() {
return [CounterReduceStore];
}
static calculateState(state: State): State {
return {
Count: CounterReduceStore.getState().Count
};
}
private input: HTMLInputElement;
private onIncrementClick: React.MouseEventHandler<HTMLButtonElement> = () => {
CounterActionsCreators.CountIncremented();
}
private onDecrementClick: React.MouseEventHandler<HTMLButtonElement> = () => {
CounterActionsCreators.CountDecremented();
}
private onResetClick: React.MouseEventHandler<HTMLButtonElement> = () => {
CounterActionsCreators.CountReset();
}
private onChangeClick: React.MouseEventHandler<HTMLButtonElement> = () => {
const value = Number(this.input.value);
if (this.input.value.length === 0 || isNaN(value)) {
alert("Hey! That's not a number!");
} else {
CounterActionsCreators.CountChanged(value);
}
}
render() {
return <div>
<div>
<span>{`Count is: ${this.state.Count} `}</span>
</div>
<div>
<button onClick={this.onIncrementClick}>Increment</button>
<button onClick={this.onDecrementClick}>Decrement</button>
<button onClick={this.onResetClick}>Reset</button>
</div>
<div>
<input ref={(input) => { this.input = input; }} defaultValue="25" />
<button onClick={this.onChangeClick}>Change</button>
</div>
</div>;
}
}
export const CounterContainer = Container.create(CounterContainerClass);
@@ -0,0 +1,55 @@
import { ReduceStore } from "simplr-flux";
import {
CountDecrementedAction,
CountIncrementedAction,
CountResetAction,
CountChangedAction
} from "./counter-actions";
interface StoreState {
Count: number;
}
class CounterReduceStoreClass extends ReduceStore<StoreState> {
constructor() {
super();
this.registerAction(CountDecrementedAction, this.onCountDecremented.bind(this));
this.registerAction(CountIncrementedAction, this.onCountIncremented.bind(this));
this.registerAction(CountResetAction, this.onCountReset.bind(this));
this.registerAction(CountChangedAction, this.onCountChanged.bind(this));
}
private onCountDecremented(action: CountDecrementedAction, state: StoreState): StoreState {
return {
Count: state.Count - 1
};
}
private onCountIncremented(action: CountIncrementedAction, state: StoreState): StoreState {
return {
Count: state.Count + 1
};
}
private onCountReset(action: CountResetAction, state: StoreState): StoreState {
return this.getInitialState();
}
private onCountChanged(action: CountChangedAction, state: StoreState): StoreState {
return {
Count: action.Count
};
}
getInitialState(): StoreState {
return {
Count: 0
};
}
public get Count(): number {
return this.getState().Count;
}
}
export const CounterReduceStore = new CounterReduceStoreClass();
Oops, something went wrong.

0 comments on commit 07ce20c

Please sign in to comment.