| 22 | * Tracks custom metadata associated with a `FieldNode`. |
| 23 | */ |
| 24 | export class FieldMetadataState { |
| 25 | /** A map of all `MetadataKey` that have been defined for this field. */ |
| 26 | private readonly metadata = new Map<MetadataKey<unknown, unknown, unknown>, unknown>(); |
| 27 | |
| 28 | constructor(private readonly node: FieldNode) {} |
| 29 | |
| 30 | /** |
| 31 | * Force eager creation of managed keys, |
| 32 | * as managed keys have a `create` function that needs to run during construction. |
| 33 | */ |
| 34 | runMetadataCreateLifecycle(): void { |
| 35 | if (!this.node.logicNode.logic.hasMetadataKeys()) { |
| 36 | return; |
| 37 | } |
| 38 | |
| 39 | const wasInParams = ɵisInParamsFunction(); |
| 40 | if (wasInParams) ɵsetInParamsFunction(false); |
| 41 | try { |
| 42 | untracked(() => |
| 43 | runInInjectionContext(this.node.structure.injector, () => { |
| 44 | for (const key of this.node.logicNode.logic.getMetadataKeys()) { |
| 45 | if (key.create) { |
| 46 | const logic = this.node.logicNode.logic.getMetadata(key); |
| 47 | const result = key.create!( |
| 48 | this.node, |
| 49 | computed(() => logic.compute(this.node.context)), |
| 50 | ); |
| 51 | this.metadata.set(key, result); |
| 52 | } |
| 53 | } |
| 54 | }), |
| 55 | ); |
| 56 | } finally { |
| 57 | if (wasInParams) ɵsetInParamsFunction(true); |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /** Gets the value of an `MetadataKey` for the field. */ |
| 62 | get<T>(key: MetadataKey<T, unknown, unknown>): T | undefined { |
| 63 | // We create non-managed metadata lazily, the first time they are accessed. |
| 64 | if (this.has(key)) { |
| 65 | if (!this.metadata.has(key)) { |
| 66 | if (key.create) { |
| 67 | throw new RuntimeError( |
| 68 | RuntimeErrorCode.MANAGED_METADATA_LAZY_CREATION, |
| 69 | ngDevMode && 'Managed metadata cannot be created lazily', |
| 70 | ); |
| 71 | } |
| 72 | const logic = this.node.logicNode.logic.getMetadata(key); |
| 73 | this.metadata.set( |
| 74 | key, |
| 75 | computed(() => logic.compute(this.node.context)), |
| 76 | ); |
| 77 | } |
| 78 | } |
| 79 | return this.metadata.get(key) as T | undefined; |
| 80 | } |
| 81 |
nothing calls this directly
no outgoing calls
no test coverage detected