Scenario
We have a set of Todo
entities that we are displaying in our Angular Material Data Table.
Our material select drop down allows us to select slices of Todo
entities based on whether we want:
- All
- Complete
- Incomplete
Approach
Dependencies
Entity Model
class Todo {
id: string;
gid?: string;
description: string;
completed: boolean;
}
Material Select Model
/**
* The Slice Keys
*/
enum TodoSliceEnum {
ALL = "All",
COMPLETE = "Complete",
INCOMPLETE = "Incomplete"
}const SELECTED_SLICE_KEY = "SELECTED_SLICE_KEY";public menus: string[] =
keys(TodoSliceEnum).map(k => TodoSliceEnum[k]);
Material Select Markup
<mat-form-field><mat-label>Todo Slice</mat-label><mat-select [formControl]="select"><mat-option *ngFor="let menu of menus" [value]="menu">{{menu}}</mat-option></mat-select></mat-form-field>
Reactive Slice Selection
We initialize our selection like this:
public ostore: OStore = new OStore();public selectedSlice$: Observable<TodoSliceEnum>;this.ostore.post(SELECTED_SLICE_KEY, TodoSliceEnum.ALL);this.selectedSlice$ = this.ostore.observe(SELECTED_SLICE_KEY);
When the user selects a slice we update the observable like this:
this.select.valueChanges.
pipe(untilDestroyed(this)).
subscribe(slice=>{
this.ostore.put(SELECTED_SLICE_KEY, slice)
})
Reactive Data Source Initialization
this.dataSource = new MatTableDataSource(todos)
Reactive Entity Store Initialization
this.allTodos$ = this.todoStore.observe()this.todoStore.addSlice(todo => todo.completed,
TodoSliceEnum.COMPLETE)this.todoStore.addSlice(todo => !todo.completed,
TodoSliceEnum.INCOMPLETE)
this.todoStore.postA(todos)this.completeTodos$ = this.todoStore
.getSlice(TodoSliceEnum.COMPLETE)
.observe()this.incompleteTodos$ = this.todoStore
.getSlice(TodoSliceEnum.INCOMPLETE)
.observe()
Getting the Selected Todos
We applyFilter
to the observables with RxJS combineLatest
in order to update the dataSource
with the the EStore
slices or all the entities:
this.selectedTodos$ = combineLatest(
this.selectedSlice$,
this.completeTodos$,
this.incompleteTodos$,
this.allTodos$,
this.applyFilter
)
The applyFilter
function:
public applyFilter(filter, completeTodos, incompleteTodos, todos): Todo[] {
switch (filter) {
case TodoSliceEnum.COMPLETE:
return completeTodos;
case TodoSliceEnum.INCOMPLETE:
return incompleteTodos;
default:
return todos;
}
}