Skip to content

Commit 6142afe

Browse files
author
Matus Kasak
committed
refactor for unique ID registry
1 parent b328fd8 commit 6142afe

File tree

3 files changed

+15
-23
lines changed

3 files changed

+15
-23
lines changed

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[formGroup]="group"
44
[ngClass]="[getClass('element', 'container'), getClass('grid', 'container')]">
55
<label *ngIf="!isCheckbox && hasLabel"
6-
[id]="'label_' + id"
6+
[id]="'label_' + model.id"
77
[for]="id"
88
[innerHTML]="(model.required && model.label) ? (model.label | translate) + ' *' : (model.label | translate)"
99
[ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]"></label>

src/app/shared/form/builder/ds-dynamic-form-ui/unique-id-registry.ts

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
export class UniqueIdRegistry {
1414

1515
/**
16-
* Tracks how many active instances exist for each base element ID.
17-
* Key = base element ID, Value = number of active instances.
16+
* Monotonic counter per base ID. Always increments, never decrements,
17+
* so released suffixes are never reissued to a different instance.
18+
* Key = base element ID, Value = next suffix to assign.
1819
*/
19-
private static idCounts: Map<string, number> = new Map<string, number>();
20+
private static nextSuffix: Map<string, number> = new Map<string, number>();
2021

2122
/**
2223
* Tracks the assigned suffix for each component instance.
@@ -40,38 +41,26 @@ export class UniqueIdRegistry {
4041
return suffix === 0 ? baseId : `${baseId}_${suffix}`;
4142
}
4243

43-
const count = this.idCounts.get(baseId) || 0;
44-
this.idCounts.set(baseId, count + 1);
45-
this.instanceSuffixes.set(instanceKey, count);
46-
return count === 0 ? baseId : `${baseId}_${count}`;
44+
const suffix = this.nextSuffix.get(baseId) || 0;
45+
this.nextSuffix.set(baseId, suffix + 1);
46+
this.instanceSuffixes.set(instanceKey, suffix);
47+
return suffix === 0 ? baseId : `${baseId}_${suffix}`;
4748
}
4849

4950
/**
5051
* Release the unique ID when a component is destroyed.
51-
* Only decrements the count when the instanceKey is still in the registry
52-
* (prevents double-release by container and child component sharing the same key).
5352
*
54-
* @param baseId The base element ID.
5553
* @param instanceKey The unique key used during registration.
5654
*/
57-
static release(baseId: string, instanceKey: string): void {
58-
if (!this.instanceSuffixes.has(instanceKey)) {
59-
return;
60-
}
55+
static release(instanceKey: string): void {
6156
this.instanceSuffixes.delete(instanceKey);
62-
const count = this.idCounts.get(baseId) || 0;
63-
if (count <= 1) {
64-
this.idCounts.delete(baseId);
65-
} else {
66-
this.idCounts.set(baseId, count - 1);
67-
}
6857
}
6958

7059
/**
71-
* Clear the entire registry. Used primarily in tests.
60+
* Clear the entire registry. Used in tests to reset state between specs.
7261
*/
7362
static clear(): void {
74-
this.idCounts.clear();
63+
this.nextSuffix.clear();
7564
this.instanceSuffixes.clear();
7665
}
7766
}

src/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
platformBrowserDynamicTesting
99
} from '@angular/platform-browser-dynamic/testing';
1010
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
11+
import { UniqueIdRegistry } from './app/shared/form/builder/ds-dynamic-form-ui/unique-id-registry';
1112

1213
// First, initialize the Angular testing environment.
1314
getTestBed().initTestEnvironment(
@@ -21,4 +22,6 @@ jasmine.getEnv().afterEach(() => {
2122
getTestBed().inject(MockStore, null)?.resetSelectors();
2223
// Close any leftover modals
2324
getTestBed().inject(NgbModal, null)?.dismissAll?.();
25+
// Reset unique ID registry to prevent static state leaking between tests
26+
UniqueIdRegistry.clear();
2427
});

0 commit comments

Comments
 (0)