Signal Actions
SignalAction has lower boilerplate and follows Angular future vision. However old state approach is same performance efficient and eas to use
Next we need to tell component that it will use TodoActions
// todos.component.ts
import { ChangeDetectionStrategy, Component, ChangeDetectorRef } from '@angular/core';
import { TodoModel } from './../actions/todo.model';
import { TodosStateActions } from './../actions/todos.actions';
import { signalActions } from '@ng-state/store';
@Component({
selector: 'todos',
templateUrl: './todos.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TodosComponent extends HasStateActions<TodosStateActions> {
actions = signalActions(TodosStateActions);
}
There are cases where state path is dynamic. For example if we are using *ngFor
directive and repeating todo.component
we need to pass not only statePath
but stateIndex
as well because statePath
is todos
and stateIndex
will be n
So final path inside of todo.component
will look like todos[stateIndex]
In this case we will create actions inside ngOnInit
// todo-item.component.ts
statePath = input<string[]>([]);
stateIndex = input<number>();
protected actions = signalActions(ResidentDetailsStateActions, { late: true });
ngOnInit(): void {
this.actions.init({
statePath: this.statePath,
stateIndex: this.stateIndex
});
}
statePath
as well as stateIndex
is passed from parent component like this:
<tr *ngFor="let todo of actions.state(); let i = index; trackBy: trackById">
<th scope="row">{{ i + 1 }}</th>
<td>{{ todo.name }}</td>
<td>
<todo-item [statePath]="actions.statePath" [stateIndex]="i"></todo-item>
</td>
<td><button class="btn btn-danger" (click)="deleteItem(i)">X</button></td>
</tr>
final actions statePath is stored in injected into propert
statePath
after actions beying constructed
stateIndex
can also be set for in cases like when you want to pass item index via URL and want to load state according to it. More documentation on section: Passing list item index via router
You can use new Angular templte syntax
@let
to not repeat signal access@let state = actions.state(); <span>{{ state.porp1 }}</span> <span>{{ state.porp2 }}</span>
Starting from v9.5.2 it is possible to use WithStore decorator and pass all required params to actions.init method in order to have store injected into actions.
this.actions.init({
statePath: this.currentStatePath(),
newPath: ['mainTab'],
initialState: {
hasChanges: false,
hasErrors: false,
hasWarnings: false,
} as TabState,
});
Last updated
Was this helpful?