A full feature directory with the observable state and presenter/container pattern contains sub-directories called presenter/containers/services/types sub-folders as described in this article:
https://georgebyte.com/scalable-angular-app-architecture/
There is a good code example of a feature directory can be found here
For our project, we can use a simpler naming convention to eliminate the sub-directories.
The categories directory can be the start of a feature director
create a items directory inside (with the observable state and presenter/container patterns)
create a service with a RxJs subject
create a container that uses the service to get the list of items
create a presentation component to display data from the container via @Input/@Output
create a view class to sync with the state store via the router url
The contents of the component and container directories are easy to determine.
However, how to implement the view and store classes as recommended from the various articles on the observable store pattern is more challenging.
This pattern involves features such as:
A dispatcher
dispatched events
initial state
application state observable
reducer function
the scan operator
the share operator
Another article about RxJs & functional reactive programming and building the app using the concepts of Redux and the single, but implementing it in Rxjs is found here
These examples are of a to do list.
How to use the application state observable section
Action Dispatcher (event bus) triggers events, and want some part of the application to be able to subscribe to the actions that it emits using an RxJs Subject
The dispatcher to be injected anywhere on the application needs an injection name. Let's start by creating such name using an OpaqueToken:
export const dispatcher = new OpaqueToken("dispatcher");
@NgModule({
...
providers: [
provide(dispatcher, {useValue: new Subject()})
]
})
export class AppModule {}
(or like this)
provide(state,
{ useFactory: applicationStateFactory,
deps: [new Inject(initialState), new Inject(dispatcher)]
})
when the system gets asked for dispatcher, this Subject will get injected.
The application state observable can be built as follows:
function applicationStateFactory(initialState, actions: Observable<Action>): Observable<ApplicationState> { ... }
reducer function for all todo-related actions:
taking a state and an action, calculate the next state of the todo list
le. Here we have the reducer function for all todo-related actions:
function calculateTodos(state: List, action) {
if (!state) {
return List([]);
}
if (action instanceof LoadTodosAction) {
return List(action.todos);
}
else if (action instanceof AddTodoAction) {
return state.push(action.newTodo);
}
else if (action instanceof ToggleTodoAction) {
return toggleTodo(state, action);
}
else if (action instanceof DeleteTodoAction) {
let index = state.findIndex((todo) => todo.id === action.todo.id);
return state.delete(index);
}
else { return state; }
}
The scan operator takes a stream and creates a new stream that provides the output of a reduce function over time.
A full feature directory with the observable state and presenter/container pattern contains sub-directories called presenter/containers/services/types sub-folders as described in this article: https://georgebyte.com/scalable-angular-app-architecture/
There is a good code example of a feature directory can be found here
For our project, we can use a simpler naming convention to eliminate the sub-directories. The categories directory can be the start of a feature director
The directory structure can look like this:
The contents of the component and container directories are easy to determine. However, how to implement the view and store classes as recommended from the various articles on the observable store pattern is more challenging.
This pattern involves features such as:
Another article about RxJs & functional reactive programming and building the app using the concepts of Redux and the single, but implementing it in Rxjs is found here
These examples are of a to do list.
How to use the application state observable section
Action Dispatcher (event bus) triggers events, and want some part of the application to be able to subscribe to the actions that it emits using an RxJs Subject
The dispatcher to be injected anywhere on the application needs an injection name. Let's start by creating such name using an OpaqueToken: export const dispatcher = new OpaqueToken("dispatcher");
(or like this)
when the system gets asked for dispatcher, this Subject will get injected.
dispatch events
initial state for the app:
The application state observable can be built as follows:
reducer function for all todo-related actions: taking a state and an action, calculate the next state of the todo list le. Here we have the reducer function for all todo-related actions:
The scan operator takes a stream and creates a new stream that provides the output of a reduce function over time.
Avoiding reducer functions from being called multiple times for one action using the share operator: