projects/i-components/src/lib/services/radioGroup.service.ts
Stores a radio button uncheck handler, along with it's given ID.
Properties |
|
constructor(id: number, uncheckHandler: () => void)
|
Creates an instance of RadioUnckeck. |
Public id |
Type : number
|
The handler's ID.
|
Public uncheckHandler |
Type : function
|
The radio button uncheck handler.
|
import { Injectable } from '@angular/core';
/**
* Stores a radio button uncheck handler, along with it's given ID.
*
* @class RadioUnckeck
*/
class RadioUnckeck {
/**
* Creates an instance of RadioUnckeck.
*
* @param {number} id The handler's ID.
* @param {() => void} uncheckHandler The radio button uncheck handler.
* @memberof RadioUnckeck
*/
constructor(public id: number, public uncheckHandler: () => void) {}
}
/**
* Represents a set of radio button uncheck handlers which belong to the
* same group.
*
* @class RadioGroup
*/
class RadioGroup {
/**
* Stores all uncheck handlers in this group.
*
* @private
* @type {RadioUnckeck[]}
* @memberof RadioGroup
*/
private handlers: RadioUnckeck[] = [];
/**
* Stores the ID which will be assigned to the
* next handler to add into the group.
*
* @private
* @memberof RadioGroup
*/
private maxId = 0;
/**
* Adds a radio button uncheck handler into the group.
* This functions return an ID which must be used to remove the handler.
*
* @param {() => void} handler The handler to add.
* @return {*} {number} The ID given to the handler.
* @memberof RadioGroup
*/
add(handler: () => void): number {
const id = this.nextId();
this.handlers.push(new RadioUnckeck(id, handler));
return id;
}
/**
* Removes the handler with the given ID from the group.
*
* @param {number} id The ID of the handler to remove.
* @memberof RadioGroup
*/
remove(id: number) {
const idx = this.handlers.findIndex((x) => x.id === id);
if (idx !== -1) {
this.handlers.splice(idx, 1);
}
}
/**
* Call all uncheck handlers in the group, except for the handler with the
* given ID.
* This should uncheck all radio buttons in the group except for one.
*
* @param {number} id The ID of the handler which should not be called.
* @memberof RadioGroup
*/
emitUncheck(id: number) {
this.handlers.forEach((x) => {
if (x.id !== id) {
x.uncheckHandler();
}
});
}
/**
* Gets the amount of handlers in this group.
*
* @readonly
* @type {number}
* @memberof RadioGroup
*/
get length(): number {
return this.handlers.length;
}
/**
* Return the next ID to assign to a handler.
*
* @private
* @return {*} {number} The ID.
* @memberof RadioGroup
*/
private nextId(): number {
return this.maxId++;
}
}
/**
* Service for the RadioButton group functionality.
*
* @export
* @class RadioGroupService
*/
@Injectable({
providedIn: 'root',
})
export class RadioGroupService {
/**
* Maps group names to groups of uncheck handlers.
*
* @private
* @type {Map<string, RadioGroup>}
* @memberof RadioGroupService
*/
private groupMap: Map<string, RadioGroup> = new Map<string, RadioGroup>();
/**
* Inserts the given handler into the corresponding group,
* and returns an ID for the handler.
*
* @param {string} groupName The name of the group.
* @param {() => any} handler The uncheck handler to insert.
* @return {*} {number} The ID assigned the handler.
* @memberof RadioGroupService
*/
subscribe(groupName: string, handler: () => any): number {
let group = this.groupMap.get(groupName);
if (group == null) {
group = new RadioGroup();
this.groupMap.set(groupName, group);
}
return group.add(handler);
}
/**
* Removes the handler with the given ID from the corresponding group.
*
* @param {string} groupName The name of the group.
* @param {number} id The ID of the handler to remove.
* @return {*} {void}
* @memberof RadioGroupService
*/
unsubscribe(groupName: string, id: number): void {
const group = this.groupMap.get(groupName);
if (group == null) {
return;
}
group.remove(id);
if (group.length === 0) {
this.groupMap.delete(groupName);
}
}
/**
* Call the radio button uncheck handlers in the given group, except for
* the handler with the given ID.
* This should uncheck all radio buttons in the group except for one.
*
* @param {string} groupName
* @param {number} id
* @return {*} {void}
* @memberof RadioGroupService
*/
emitUncheck(groupName: string, id: number): void {
const group = this.groupMap.get(groupName);
if (group == null) {
return;
}
group.emitUncheck(id);
}
}