-
Notifications
You must be signed in to change notification settings - Fork 405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🚀[FEATURE]: Allow Actions with non-static type fields #2092
Comments
This is not a particularly common requirement and one that adds a layer of indirection that is not something that we would recommend for most codebases. We would recommend explicitly defined actions for traceability, debugability and clarity. The other challenge is that the I would recommend that you just include the That being said, it could be possible to achieve some of what you are looking for with a class factory function to create many different action classes from the same template. function createAddTodoActionClass(context: string) {
return class AddTodoAction {
static readonly type = '`[${context}] Add Todo`';
constructor(public todo: Todo) {}
}
}
export const AddOverviewTodoAction = createAddTodoActionClass('Overview');
export const AddDetailTodoAction = createAddTodoActionClass('Detail'); Applying similar principles, you could also achieve your dynamic case: export class AddTodoAction {
constructor(context: string, public todo: Todo) {
const actionClass = createAddTodoActionClass(context);
// returns a new object from the constructor function
return new actionClass(todo);
}
} BUT, I would seriously consider making the dynamic |
My creativity ran loose on this one... You could use this It would be used as follows: // in your action file
class AddTodoActionBase {
static readonly type = `Add Todo`;
constructor(public todo: Todo) {}
}
export const AddTodoAction = createDynamicAction(AddTodoActionBase);
// If you want to create explicit, known types
export const AddOverviewTodoAction = AddTodoAction('Overview');
export const AddDetailTodoAction = AddTodoAction('Detail'); Here are some examples of dispatching the various actions: const t = new Todo();
store.dispatch(new AddOverviewTodoAction(t));
store.dispatch(new AddDetailTodoAction(t));
store.dispatch(new AddTodoAction('hi', t)); And in your state you can use the action decorator like this: @Action(AddOverviewTodoAction)
addOverviewTodoAction( ctx /*... etc */) {}
@Action(AddDetailTodoAction)
addDetailTodoAction( ctx /*... etc */) {}
@Action(AddTodoAction('hi'))
addHiTodoAction( ctx /*... etc */) {} Let me know if it helps you ;-) |
Relevant Package
This feature request is for @ngxs/store
Description
Actions should allow a non-static 'type' field
Instead of:
I would like to do the following:
Describe the problem you are trying to solve
In your documenation it states that Actions should ideally follow a name pattern like this:
[User API] GetUser
.Basically,
[<Origin of the Event>] <Verb><Entity>
With the current implementation the only way to achieve this is by creating a separate class for every possible origin where this action could be dispatched from.
This gets incredibly verbose very quickly. I guess for this reason even the documentation does not continue to use this pattern but instead falls back to this:
Describe the solution you'd like
I think something like this could be good:
I'm sorry i have not dug deep into the sourcecode, but it seems that parts of ngxs already recognize non-static type fields.
I can dispatch the action, the @ngxs/devtools-plugin shows the name correctly, but creating an Actionhandler for this Action does not work:
TS2345: Argument of type typeof AddTodoAction is not assignable to parameter of type ActionType | ActionType[] Property type is missing in type typeof AddTodoAction but required in type ActionDef<any, any>
So, maybe this is just a bug
Describe alternatives you've considered
I've tried working around with static fields but i found no clean solution.
The text was updated successfully, but these errors were encountered: