Skip to content

Commit

Permalink
feat: ivy UseStoreon hook
Browse files Browse the repository at this point in the history
  • Loading branch information
valburyakov committed Jul 11, 2019
1 parent a81d8db commit 0654726
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 17 deletions.
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@ export const defaultStore = createStore<State, Events>([counterModule, !environm

// your NgModule

import { StoreonModule, STOREON } from '@storeon/angular';
import { STOREON } from '@storeon/angular';

@NgModule({
imports: [StoreonModule], // StoreonModule
...
providers: [{
provide: STOREON,
useValue: defaultStore // your store
Expand Down Expand Up @@ -98,3 +96,36 @@ export class AppComponent implements OnInit {
}

```
```typescript

// example using Ivy hooks

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { UseStoreon } from '@storeon/angular';
import { Events, State } from '../app.module';
import { Dispatch } from 'storeon';

@Component({
selector: 'app-hook-counter',
templateUrl: './hook-counter.component.html',
styleUrls: ['./hook-counter.component.scss']
})
@UseStoreon<State, Events>({keys: [ 'count' ], dispatcher: 'dispatch'})
export class HookCounterComponent implements OnInit {

count: Observable<number>;
dispatch: Dispatch<Events>;

constructor() { }

ngOnInit() {
}

increment() {
this.dispatch('inc');
}
}

```
32 changes: 32 additions & 0 deletions projects/ng-storeon/src/lib/storeon.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ɵɵdirectiveInject as directiveInject } from '@angular/core';
import { StoreonService } from './storeon.service';


/***
*
* Experimental feature, works only with Ivy renderer
* Patches the component with keys from storeon store
*
*/
export function UseStoreon<State, Events>(config: {
keys: Array<keyof State>,
dispatcher?: string
}) {
return (cmpType) => {
const originalFactory = cmpType.ngComponentDef.factory;
cmpType.ngComponentDef.factory = () => {
const cmp = originalFactory(cmpType.ngComponentDef.type);

const storeon = directiveInject<StoreonService<State, Events>>(StoreonService );

config.keys.forEach(key => cmp[key] = storeon.useStoreon(key));

if (config.dispatcher) {
cmp[config.dispatcher] = storeon.dispatch.bind(storeon);
}

return cmp;
};

};
}
10 changes: 0 additions & 10 deletions projects/ng-storeon/src/lib/storeon.module.ts

This file was deleted.

2 changes: 1 addition & 1 deletion projects/ng-storeon/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
*/

export * from './lib/storeon.service';
export * from './lib/storeon.module';
export * from './lib/storeon.token';
export * from './lib/storeon.decorator';
4 changes: 3 additions & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { Routes, RouterModule } from '@angular/router';

import { CounterComponent } from './counter/counter.component';
import { Counter1Component } from './counter1/counter1.component';
import { HookCounterComponent } from './hook-counter/hook-counter.component';

const routes: Routes = [
{ path: 'counter', component: CounterComponent },
{ path: 'counter1', component: Counter1Component }
{ path: 'counter1', component: Counter1Component },
{ path: 'ivy-hook', component: HookCounterComponent }
];

@NgModule({
Expand Down
5 changes: 3 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { StoreonModule, STOREON } from '@storeon/angular';
import { STOREON } from '@storeon/angular';

import createStore, { Module, StoreonEvents } from 'storeon';
import devtools from 'storeon/devtools';
Expand All @@ -12,6 +12,7 @@ import { AppComponent } from './app.component';
import { MenuComponent } from './menu/menu.component';
import { CounterComponent } from './counter/counter.component';
import { Counter1Component } from './counter1/counter1.component';
import { HookCounterComponent } from './hook-counter/hook-counter.component';

// State structure
export interface State {
Expand Down Expand Up @@ -43,11 +44,11 @@ export const defaultStore = createStore<State, Events>([counterModule, !environm
MenuComponent,
CounterComponent,
Counter1Component,
HookCounterComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
StoreonModule
],
providers: [{
provide: STOREON,
Expand Down
4 changes: 4 additions & 0 deletions src/app/hook-counter/hook-counter.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
<button (click)="increment()">Increment counter</button>
<span>Total count: {{ count | async }}</span>
</div>
Empty file.
25 changes: 25 additions & 0 deletions src/app/hook-counter/hook-counter.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { HookCounterComponent } from './hook-counter.component';

describe('HookCounterComponent', () => {
let component: HookCounterComponent;
let fixture: ComponentFixture<HookCounterComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HookCounterComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(HookCounterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
26 changes: 26 additions & 0 deletions src/app/hook-counter/hook-counter.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { UseStoreon } from '@storeon/angular';
import { Events, State } from '../app.module';
import { Dispatch } from 'storeon';

@Component({
selector: 'app-hook-counter',
templateUrl: './hook-counter.component.html',
styleUrls: ['./hook-counter.component.scss']
})
@UseStoreon<State, Events>({keys: [ 'count' ], dispatcher: 'dispatch'})
export class HookCounterComponent implements OnInit {

count: Observable<number>;
dispatch: Dispatch<Events>;

constructor() { }

ngOnInit() {
}

increment() {
this.dispatch('inc');
}
}
1 change: 1 addition & 0 deletions src/app/menu/menu.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<ul>
<li><a [routerLink]="['/counter']" routerLinkActive="router-link-active">Counter</a></li>
<li><a [routerLink]="['/ivy-hook']" routerLinkActive="router-link-active">Counter with Ivy Hook</a></li>
<li><a [routerLink]="['/counter1']" routerLinkActive="router-link-active">Counter 1</a></li>
</ul>

0 comments on commit 0654726

Please sign in to comment.