Skip to content

Commit

Permalink
Implement a Signals based service
Browse files Browse the repository at this point in the history
  • Loading branch information
sondreb committed Jun 19, 2024
1 parent 7211cb5 commit 36780c6
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
15 changes: 15 additions & 0 deletions app/src/app/settings.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Injectable } from '@angular/core';
import { SignalsSimpleStoreService } from './signals.service';

export interface SettingsState {
language: string;
debug: boolean;
servers: string[];
}

@Injectable()
export class SettingsStateService extends SignalsSimpleStoreService<SettingsState> {
constructor() {
super();
}
}
12 changes: 11 additions & 1 deletion app/src/app/settings/settings.component.html
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
<p>settings works!</p>
<h1>Settings</h1>

<br>
Debug: {{ settings().debug }}
<br>
Servers: {{ settings().servers }}
<br>
Language: {{ settings().language }}
<br>
<br>
<button mat-flat-button (click)="toggleDebug()">Toggle debug</button>
25 changes: 22 additions & 3 deletions app/src/app/settings/settings.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { SettingsState, SettingsStateService } from '../settings.service';
import { MatButtonModule } from '@angular/material/button';

@Component({
selector: 'app-settings',
standalone: true,
imports: [],
imports: [MatButtonModule],
templateUrl: './settings.component.html',
styleUrl: './settings.component.scss'
styleUrl: './settings.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [SettingsStateService]
})
export class SettingsComponent {

debug = this.settingsState.select('debug');

readonly settings = this.settingsState.state.asReadonly();

constructor(private settingsState: SettingsStateService) {

}

toggleDebug() {
// Update single property
//this.settingsState.set('debug', !this.settings().debug);

// Update full or partial state
this.settingsState.setState({ debug: !this.settings().debug } as SettingsState);
}
}
40 changes: 40 additions & 0 deletions app/src/app/signals.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Signal, computed, signal } from "@angular/core";

export class SignalsSimpleStoreService<T> {
readonly state = signal({} as T);

constructor() {}

/**
* Returns a reactive value for a property on the state.
* This is used when the consumer needs the signal for
* specific part of the state.
*
* @param key - the key of the property to be retrieved
*/
public select<K extends keyof T>(key: K): Signal<T[K]> {
return computed(() => this.state()[key]);
}

/**
* This is used to set a new value for a property
*
* @param key - the key of the property to be set
* @param data - the new data to be saved
*/
public set<K extends keyof T>(key: K, data: T[K]) {
this.state.update((currentValue) => ({ ...currentValue, [key]: data }));
}

/**
* Sets values for multiple properties on the store
* This is used when there is a need to update multiple
* properties in the store
*
* @param partialState - the partial state that includes
* the new value to be saved
*/
public setState(partialState: Partial<T>): void {
this.state.update((currentValue) => ({ ...currentValue, ...partialState }));
}
}

0 comments on commit 36780c6

Please sign in to comment.