Skip to content

Commit

Permalink
feat(*): Typescript Port (angular-redux#33)
Browse files Browse the repository at this point in the history
* Adds .idea (intellij IDE) to .gitignore
* Ports the library to TypeScript, and adds (basic) generic support
* Examples now work with Typed Stores, and Angular 2 Beta 1
* Upgraded tsd to typings
* Updates/prunes dependencies adds postinstall for typings to the example
* Purge typings
* Fixes typings postinstall when used as a dependency
* Updates typings and excludes tmp from tsconfig
* Fix reflect-metadata issue
* Fix counter and dev tools
* Remove lib folder
* Update counter to load ng2-redux from src
* Update webpack config
* Ports the library to TypeScript, and adds (basic) generic support
* Update peer dependencies
* Lock down versions
* Adds redux-logger typings/dependency
* Tests are now TypeScript
* Remove old service code from provider.ts
* Left ng-redux.ts as own file
* Fix exports from src/index.ts
* Remove extra 'reflect-metadata' from counter example
* chore(tests) Add typings for mocha and chai
* add chai to dev dep
* update node version for tests
* Observable Store and official redux typings
* Remove js version of connector spec
* Add ability to provide a custom compare function to .select
* Fix path to index.d.ts
* Update contributors on package.json
* Cleanup example
* Update readme with .select details
* Change provider to use NgRedux class directly
* Add alias for @Inject('ngRedux')

To prevent breaking changes from people using @Inject('ngRedux'), setup
an alias so that code using this style of injection will still work.

* refactor(connector) Merge ng-redux and connector

Refactored connector so all of the ng-redux.ts functionality was moved
into it, then renamed it.

* Updated tests, and cleaned up the provide factory.
* Fix type issue for action creator
* chore(readme) Update bootstrap
* No longer need to register NgRedux directly as a provider
* docs(ngRedux): Add docs to public api methods (angular-redux#35)
* chore(package): Update repo details (angular-redux#36)
* chore(ci): Setup circleci (angular-redux#37)
* chore(ci): Setup circleci
* chore(ci): Change badge to be circleci (angular-redux#38)
* Chore ci changes (angular-redux#39)
* chore(ci): remove .travis.yml
* chore(ci): Change node version
* Chore/example project cleanup (angular-redux#52)
* chore(example): use npm package instead of source.
* Prefer the chrome extension dev tools in README (angular-redux#50)

This is because they don't require a dependency on React.

Also showed an example of enabling Angular 2 to refresh after events fired by the dev tools.

* Dependency cleanup, minor corrections to example devtools. (angular-redux#55)
* Core changelog (angular-redux#53)

* add changelog
  • Loading branch information
e-schultz authored and smithad15 committed Jul 9, 2018
1 parent 9b5a9fc commit 33ea991
Show file tree
Hide file tree
Showing 47 changed files with 1,021 additions and 2,436 deletions.
2 changes: 1 addition & 1 deletion packages/store/.babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"stage": 0,
"loose": "all"
}
}
10 changes: 8 additions & 2 deletions packages/store/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
node_modules/
lib/
*.tgz
examples/counter/dist/components/*
examples/counter/dist/containers/*
examples/counter/dist/index.*
examples/counter/dist/index.*
.idea
npm-debug.log
examples/counter/typings/
src/typings/
typings/
tmp/
lib/
6 changes: 5 additions & 1 deletion packages/store/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
src
test
examples
examples
.travis.yml
.gitignore
.babelrc
lib/___tests___
3 changes: 0 additions & 3 deletions packages/store/.travis.yml

This file was deleted.

61 changes: 61 additions & 0 deletions packages/store/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# 2.2.2

### Features

* **type definitions**:
* Ported to typescript
* Supports typed stores / reducers
* Uses offical Redux type definitions
* **Type Injectable**:
* Able to inject `NgRedux` into your component by type, and not need `@Inject('ngRedux')`
* `@Inject('ngRedux')` still works

```ts
import { NgRedux } from 'ng2-redux';
// ...
export class MyComponent {
constructor(private ngRedux: NgRedux) {
}
}
```
* **State as Observable**: Ability to expose parts of your state as an observable.

```ts
select<S>(selector: string | number | symbol | ((state: RootState) => S), comparer?: (x: any, y: any) => boolean): Observable<S>;
wrapActionCreators: (actions: any) => (dispatch: Redux.Dispatch<any>) => Redux.ActionCreator<{}> | Redux.ActionCreatorsMapObject;
```

Example use:

```js
import { NgRedux } from 'ng2-redux';
// ...
export class MyComponent implements OnInit {
countByKey$: Observable<number>;
countByFunc$: Observable<number>;
constructor(private ngRedux: NgRedux) {
}
ngOnInit() {
this.countByKey$ = this.ngRedux.select('count');
this.countByFunc$ = this.ngRedux.select(state=>state.count);
}
}
```

Also have the ability to provide a custom compare function.

```js
import { is, Map } from 'immutable';
import { NgRedux } from 'ng2-redux';

// ...
export class MyComponent implements OnInit {
person$: Observable<Map<string,any>>;
constructor(private ngRedux: ngRedux) { }
ngOnInit() {
// even if the reference of the object has changed,
// if the data is the same - it wont be treated as a change
this.person$ = this.ngRedux.select(state=>state.people.get(0),is);
}
}
```
119 changes: 112 additions & 7 deletions packages/store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

For Angular 1 see [ng-redux](https://github.com/wbuchwalter/ng-redux)

[![build status](https://img.shields.io/travis/wbuchwalter/ng2-redux/master.svg?style=flat-square)](https://travis-ci.org/wbuchwalter/ng2-redux)
[![Circle CI](https://circleci.com/gh/angular-redux/ng2-redux/tree/master.svg?style=svg)](https://circleci.com/gh/angular-redux/ng2-redux/tree/master)
[![npm version](https://img.shields.io/npm/v/ng2-redux.svg?style=flat-square)](https://www.npmjs.com/package/ng2-redux)

ngRedux lets you easily connect your angular components with Redux.
Expand All @@ -24,7 +24,7 @@ npm install --save ng2-redux

## Quick Start

#### Initialization
### Initialization

```JS
import {bootstrap} from 'angular2/platform/browser';
Expand All @@ -45,11 +45,41 @@ bootstrap(

#### Usage

`ng2-redux` has two ways that it can be used. The first way is using the `ngRedux.connect` API, which will map the state and dispatch actions to the provided target.

There is also `ngRedux.select`, which will expose a slice of your state as an RxJs observable.


#### ngRedux.select
```JS
import * as CounterActions from '../actions/CounterActions';
import {NgRedux} from 'ng2-redux';
import {Observable} from 'rxjs';

class CounterApp {
count$: Observable<number>;
counterSubscription: Function;

constructor(private ngRedux: NgRedux) { }

ngOnInit() {
this.count$ = this.ngRedux
.select(n=>n.counter)
this.ngRedux.mapDispatchToTarget(CounterActions)

}

}
```

#### ngRedux.connect

```JS
import * as CounterActions from '../actions/CounterActions';
import {NgRedux} from 'ng2-redux';

class CounterApp {
constructor( @Inject('ngRedux') ngRedux) {
constructor(ngRedux: NgRedux) {
this.unsubscribe = ngRedux.connect(this.mapStateToThis, this.mapDispatchToThis)(this);
}

Expand All @@ -71,6 +101,7 @@ class CounterApp {
}
```


## API

### `provider(store)`
Expand Down Expand Up @@ -98,11 +129,35 @@ connect(this.mapStateToThis, this.mapDispatchToThis)(this);
connect(this.mapState, this.mapDispatch)((selectedState, actions) => {/* ... */});
```


#### Remarks
* The `mapStateToTarget` function takes a single argument of the entire Redux store’s state and returns an object to be passed as props. It is often called a selector. Use reselect to efficiently compose selectors and compute derived data.


### select(key | function,[comparer]) => Observable

Exposes a slice of state as an observable. Accepts either a key-path, or a selector function.

If using the async pipe, you do not need to subscribe to it explicitly, but can use the angular Async pipe to observe for values.

#### Arguments

* `key` \(*string*): A key within the state that you want to subscribe to.
* `selector` \(*Function*): A function that accepts the application state, and returns the slice you want subscribe to for changes.


e.g:
```JS
this.counter$ = this.ngRedux.select(state=>state.counter);
// or
this.counterSubscription = this.ngRedux
.select(state=>state.counter)
.subscribe(count=>this.counter = count);
// or

this.counter$ = this.ngRedux.select('counter');
```


### Store API
All of redux's store methods (i.e. `dispatch`, `subscribe` and `getState`) are exposed by $ngRedux and can be accessed directly. For example:

Expand All @@ -115,9 +170,59 @@ ngRedux.subscribe(() => {

This means that you are free to use Redux basic API in advanced cases where `connect`'s API would not fill your needs.


## Using DevTools

In order to use Redux DevTools with your angular app, you need to install [react](https://www.npmjs.com/package/react), [react-redux](https://www.npmjs.com/package/react-redux) and [redux-devtools](https://www.npmjs.com/package/redux-devtools) as development dependencies.
Ng2Redux is fully compatible with the Chrome extension version of the Redux dev tools:

https://github.com/zalmoxisus/redux-devtools-extension

Here's how to enable them in your app (you probably only want to do
this in development mode):

You can find a sample devtools implentation in the [counter example](https://github.com/wbuchwalter/ng2-redux/blob/master/examples/counter/devTools.js)
1. Add the extension to your storeEnhancers:

```typescript
const enhancers = [];

// Add Whatever other enhancers you want.

if (__DEVMODE__ && window.devToolsExtension) {
enhancers = [ ...enhancers, window.devToolsExtension() ];
}

const store = compose(
applyMiddleware(middleware),
...enhancers
)(createStore)(rootReducer, initialState);
```

2. Make Angular 2 update when store events come from the dev tools
instead of Ng2Redux:

```typescript
@Component({
// etc.
})
export class App {
private unsubscribe: () => void;

constructor(
private ngRedux: NgRedux<IAppState>,
applicationRef: ApplicationRef) {

// etc.

if (__DEVMODE__) {
this.unsubscribe = ngRedux.subscribe(() => {
applicationRef.tick();
});
}
}

ngOnDestroy() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
};
```
3 changes: 3 additions & 0 deletions packages/store/circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
machine:
node:
version: 4.4.3
6 changes: 4 additions & 2 deletions packages/store/examples/counter/actions/CounterActions.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
export const INCREMENT_COUNTER:string = 'INCREMENT_COUNTER';
export const DECREMENT_COUNTER:string = 'DECREMENT_COUNTER';
import * as Redux from 'redux';


export var increment = () => {
return {
return <Redux.Action>{
type: INCREMENT_COUNTER
};
}

export var decrement = () => {
return {
return <Redux.Action>{
type: DECREMENT_COUNTER
};
}
Expand Down
18 changes: 9 additions & 9 deletions packages/store/examples/counter/components/Counter.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import {Component} from 'angular2/core';
import {Component, Input} from 'angular2/core';

@Component({
selector: 'counter',
inputs: [
'counter',
'increment',
'decrement',
'incrementIfOdd',
'incrementAsync'
],
template: `
<p>
Clicked: {{ counter }} times
Expand All @@ -19,4 +12,11 @@ import {Component} from 'angular2/core';
</p>
`
})
export class Counter {}
export class Counter {
@Input() counter: number;
@Input() increment: () => void;
@Input() decrement: () => void;
@Input() incrementIfOdd: () => void;
@Input() incrementAsync: () => void;

}

0 comments on commit 33ea991

Please sign in to comment.