Hi,
I’m working with the Aurelia Store and I’d like to get a quite similar flexibility as it is proposed in VueJS. The idea is to get the dispatchified actions easily accessible from any class.
I got the following code working as proof of concept. The idea is to have a central place for the actions definition and implementation. Then, when inovking the actions, we in fact invoke the dispatchified version of it.
store.ts
import { dispatchify, connectTo, Store, Reducer } from 'aurelia-store';
import { State, initialState } from 'state';
import { autoinject } from 'aurelia-framework';
class Actions
{
protected state: State;
protected newState: State;
public addName(name: string){
this.newState.names = [...this.newState.names, name];
return this.newState;
};
public setState(newState: State){
return newState;
};
public resetState()
{
return initialState;
}
}
// Transforms action into dispatchable action
// => adds state as first argument and add a clone of state
// to work with
function actionify(func: Function)
{
return function(state: State, ...args)
{
let context ={
state: state,
newState: Object.assign({}, state)
};
return func.apply(context, args);
}
}
/**
* StoreAction: extend from this class to get
* access to implemented actions from the class Actions
* => call to the action method will in fact invoke the dispatchified version
* of the action.
*/
@autoinject()
@connectTo()
export class StoreAction extends Actions
{
constructor(protected store: Store<State>)
{
super();
for(let action of Object.getOwnPropertyNames(Actions.prototype))
{
if(action != 'constructor')
{
this.store.registerAction(action, actionify(Actions.prototype[action]));
StoreAction.prototype[action] = dispatchify(action);
}
}
}
}
app.ts
import { StoreAction } from './store';
import { autoinject } from 'aurelia-framework';
@autoinject()
export class App extends StoreAction
{
message = 'Hello World! Test';
onClick()
{
console.log(this.state) // <-- We have access to the state
this.addName("my name"); // <--- We dispatch an action here
}
}
What do you think?