State and feature state
The state is the global object that contains all data to be shared among components and with a lifetime greater than a component's lifetime.
The state contains all the defined feature states.
Note
The state must be immutable but, to keep it simple, the state remains a simple javascript object. This is the responsibility of the coder to guarantee immutability of the state.
Static definition of a feature state
The static way of providing a feature state is to use the decorator NgSsmFeatureState.
export const NgSsmFeatureState = (specification: FeatureStateSpecification) => {
return (target: object) => {
featureStateSpecifications.push(specification);
};
};
A feature state can be generated with schematics. For example:
with the generated file
import update, { Spec } from 'immutability-helper';
import { NgSsmFeatureState, State } from 'ngssm-store';
export const selectTestFeatureStateState = (state: State): TestFeatureStateState =>
state[TestFeatureStateStateSpecification.featureStateKey] as TestFeatureStateState;
export const updateTestFeatureStateState = (state: State, command: Spec<TestFeatureStateState, never>): State =>
update(state, {
[TestFeatureStateStateSpecification.featureStateKey]: command
});
export interface TestFeatureStateState {}
@NgSsmFeatureState({
featureStateKey: TestFeatureStateStateSpecification.featureStateKey,
initialState: TestFeatureStateStateSpecification.initialState
})
export class TestFeatureStateStateSpecification {
public static readonly featureStateKey = 'test-feature-state-state';
public static readonly initialState: TestFeatureStateState = {};
}
Dynamic registration of a feature state
In order to allow associating a feature state to a component and so, to remove that state when the component is destroyed, a feature state could also be registered at any time.
Note
As the static registration of feature state will be removed in a future release, this is the way to register any feature state.
Two actions are provided to register and unregister feature state:
import { Action } from '../action';
import { NgssmStoreActionType } from './ngssm-store-action-type';
export class NgssmRegisterFeatureStateAction implements Action {
public readonly type: string = NgssmStoreActionType.registerFeatureState;
constructor(
public readonly featureStateKey: string,
public readonly initialValue: object
) {}
}
export class NgssmUnregisterFeatureStateAction implements Action {
public readonly type: string = NgssmStoreActionType.unregisterFeatureState;
constructor(public readonly featureStateKey: string) {}
}
When using a global feature state, one can use the function provideNgssmFeatureState as follows
export const appConfig: ApplicationConfig = {
providers: [provideNgssmFeatureState('my-feature-state', { description: 'something' })]
};
When using a feature state with a component lifetime, one can use the directive ProvideNgssmFeatureStateDirective as follows
import { Component } from '@angular/core';
import { ProvideNgssmFeatureStateDirective } from './provide-ngssm-feature-state.directive';
import { FeatureStateSpecification, NGSSM_COMPONENT_WITH_FEATURE_STATE } from './feature-state-specification';
@Component({
selector: 'ngssm-provide-ngssm-feature-state-directive-test',
imports: [],
template: ` <p>provide-ngssm-feature-state-directive-test works!</p> `,
styles: ``,
hostDirectives: [ProvideNgssmFeatureStateDirective],
providers: [
{
provide: NGSSM_COMPONENT_WITH_FEATURE_STATE,
multi: false,
useExisting: ProvideNgssmFeatureStateDirectiveTestComponent
}
]
})
export class ProvideNgssmFeatureStateDirectiveTestComponent implements FeatureStateSpecification {
featureStateKey = 'my-feature-state';
initialState = {
id: 'testing'
};
}