mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
refactor(forms): rename field state related to metdata (#64603)
Renames the field state related to metadata to reflect the new "metadata" name. In particular: - `property(...)` is renamed to `metadata(...)` - `hasProperty(...)` is renamed to `hasMetadata(...)` PR Close #64603
This commit is contained in:
parent
f3c547b750
commit
a6a5fd7b7d
19 changed files with 94 additions and 98 deletions
|
|
@ -162,7 +162,7 @@ export function validateAsync<TValue, TParams, TResult, TPathKind extends PathKi
|
|||
});
|
||||
|
||||
pathNode.logic.addAsyncErrorRule((ctx) => {
|
||||
const res = ctx.state.property(RESOURCE)!;
|
||||
const res = ctx.state.metadata(RESOURCE)!;
|
||||
switch (res.status()) {
|
||||
case 'idle':
|
||||
return undefined;
|
||||
|
|
|
|||
|
|
@ -299,21 +299,21 @@ export interface FieldState<TValue, TKey extends string | number = string | numb
|
|||
readonly fieldBindings: Signal<readonly Field<unknown>[]>;
|
||||
|
||||
/**
|
||||
* Reads an aggregate property value from the field.
|
||||
* @param prop The property to read.
|
||||
* Reads an aggregate metadata value from the field.
|
||||
* @param key The metadata key to read.
|
||||
*/
|
||||
property<M>(prop: AggregateMetadataKey<M, any>): Signal<M>;
|
||||
metadata<M>(key: AggregateMetadataKey<M, any>): Signal<M>;
|
||||
|
||||
/**
|
||||
* Reads a property value from the field.
|
||||
* @param prop The property key to read.
|
||||
* Reads a metadata value from the field.
|
||||
* @param key The metadata key to read.
|
||||
*/
|
||||
property<M>(prop: MetadataKey<M>): M | undefined;
|
||||
metadata<M>(key: MetadataKey<M>): M | undefined;
|
||||
|
||||
/**
|
||||
* Checks whether the given metadata key has been defined for this field.
|
||||
*/
|
||||
hasProperty(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean;
|
||||
hasMetadata(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean;
|
||||
|
||||
/**
|
||||
* Resets the {@link touched} and {@link dirty} state of the field and its descendants.
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ export function max<TPathKind extends PathKind = PathKind.Root>(
|
|||
const MAX_MEMO = metadata(path, (ctx) =>
|
||||
computed(() => (typeof maxValue === 'number' ? maxValue : maxValue(ctx))),
|
||||
);
|
||||
aggregateMetadata(path, MAX, ({state}) => state.property(MAX_MEMO)!());
|
||||
aggregateMetadata(path, MAX, ({state}) => state.metadata(MAX_MEMO)!());
|
||||
validate(path, (ctx) => {
|
||||
if (isEmpty(ctx.value())) {
|
||||
return undefined;
|
||||
}
|
||||
const max = ctx.state.property(MAX_MEMO)!();
|
||||
const max = ctx.state.metadata(MAX_MEMO)!();
|
||||
if (max === undefined || Number.isNaN(max)) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ export function maxLength<
|
|||
const MAX_LENGTH_MEMO = metadata(path, (ctx) =>
|
||||
computed(() => (typeof maxLength === 'number' ? maxLength : maxLength(ctx))),
|
||||
);
|
||||
aggregateMetadata(path, MAX_LENGTH, ({state}) => state.property(MAX_LENGTH_MEMO)!());
|
||||
aggregateMetadata(path, MAX_LENGTH, ({state}) => state.metadata(MAX_LENGTH_MEMO)!());
|
||||
validate(path, (ctx) => {
|
||||
if (isEmpty(ctx.value())) {
|
||||
return undefined;
|
||||
}
|
||||
const maxLength = ctx.state.property(MAX_LENGTH_MEMO)!();
|
||||
const maxLength = ctx.state.metadata(MAX_LENGTH_MEMO)!();
|
||||
if (maxLength === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ export function min<TPathKind extends PathKind = PathKind.Root>(
|
|||
const MIN_MEMO = metadata(path, (ctx) =>
|
||||
computed(() => (typeof minValue === 'number' ? minValue : minValue(ctx))),
|
||||
);
|
||||
aggregateMetadata(path, MIN, ({state}) => state.property(MIN_MEMO)!());
|
||||
aggregateMetadata(path, MIN, ({state}) => state.metadata(MIN_MEMO)!());
|
||||
validate(path, (ctx) => {
|
||||
if (isEmpty(ctx.value())) {
|
||||
return undefined;
|
||||
}
|
||||
const min = ctx.state.property(MIN_MEMO)!();
|
||||
const min = ctx.state.metadata(MIN_MEMO)!();
|
||||
if (min === undefined || Number.isNaN(min)) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ export function minLength<
|
|||
const MIN_LENGTH_MEMO = metadata(path, (ctx) =>
|
||||
computed(() => (typeof minLength === 'number' ? minLength : minLength(ctx))),
|
||||
);
|
||||
aggregateMetadata(path, MIN_LENGTH, ({state}) => state.property(MIN_LENGTH_MEMO)!());
|
||||
aggregateMetadata(path, MIN_LENGTH, ({state}) => state.metadata(MIN_LENGTH_MEMO)!());
|
||||
validate(path, (ctx) => {
|
||||
if (isEmpty(ctx.value())) {
|
||||
return undefined;
|
||||
}
|
||||
const minLength = ctx.state.property(MIN_LENGTH_MEMO)!();
|
||||
const minLength = ctx.state.metadata(MIN_LENGTH_MEMO)!();
|
||||
if (minLength === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ export function pattern<TPathKind extends PathKind = PathKind.Root>(
|
|||
const PATTERN_MEMO = metadata(path, (ctx) =>
|
||||
computed(() => (pattern instanceof RegExp ? pattern : pattern(ctx))),
|
||||
);
|
||||
aggregateMetadata(path, PATTERN, ({state}) => state.property(PATTERN_MEMO)!());
|
||||
aggregateMetadata(path, PATTERN, ({state}) => state.metadata(PATTERN_MEMO)!());
|
||||
validate(path, (ctx) => {
|
||||
if (isEmpty(ctx.value())) {
|
||||
return undefined;
|
||||
}
|
||||
const pattern = ctx.state.property(PATTERN_MEMO)!();
|
||||
const pattern = ctx.state.metadata(PATTERN_MEMO)!();
|
||||
if (pattern === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ export function required<TValue, TPathKind extends PathKind = PathKind.Root>(
|
|||
const REQUIRED_MEMO = metadata(path, (ctx) =>
|
||||
computed(() => (config?.when ? config.when(ctx) : true)),
|
||||
);
|
||||
aggregateMetadata(path, REQUIRED, ({state}) => state.property(REQUIRED_MEMO)!());
|
||||
aggregateMetadata(path, REQUIRED, ({state}) => state.metadata(REQUIRED_MEMO)!());
|
||||
validate(path, (ctx) => {
|
||||
if (ctx.state.property(REQUIRED_MEMO)!() && isEmpty(ctx.value())) {
|
||||
if (ctx.state.metadata(REQUIRED_MEMO)!() && isEmpty(ctx.value())) {
|
||||
if (config?.error) {
|
||||
return getOption(config.error, ctx);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export function validateStandardSchema<TSchema, TValue extends IgnoreUnknownProp
|
|||
});
|
||||
validateTree(path, ({state, fieldOf}) => {
|
||||
// Skip sync validation if the result is a Promise.
|
||||
const result = state.property(VALIDATOR_MEMO)!();
|
||||
const result = state.metadata(VALIDATOR_MEMO)!();
|
||||
if (ɵisPromise(result)) {
|
||||
return [];
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ export function validateStandardSchema<TSchema, TValue extends IgnoreUnknownProp
|
|||
validateAsync(path, {
|
||||
params: ({state}) => {
|
||||
// Skip async validation if the result is *not* a Promise.
|
||||
const result = state.property(VALIDATOR_MEMO)!();
|
||||
const result = state.metadata(VALIDATOR_MEMO)!();
|
||||
return ɵisPromise(result) ? result : undefined;
|
||||
},
|
||||
factory: (params) => {
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ export class InteropNgControl
|
|||
// This addresses a common case where users look for the presence of `Validators.required` to
|
||||
// determine whether or not to show a required "*" indicator in the UI.
|
||||
if (validator === Validators.required) {
|
||||
return this.field().property(REQUIRED)();
|
||||
return this.field().metadata(REQUIRED)();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import {FieldPathNode} from '../schema/path_node';
|
|||
import {FieldNodeContext} from './context';
|
||||
import type {FieldAdapter} from './field_adapter';
|
||||
import type {FormFieldManager} from './manager';
|
||||
import {FieldPropertyState} from './property';
|
||||
import {FieldMetadataState} from './property';
|
||||
import {FIELD_PROXY_HANDLER} from './proxy';
|
||||
import {FieldNodeState} from './state';
|
||||
import {
|
||||
|
|
@ -53,7 +53,7 @@ import {ValidationState} from './validation';
|
|||
export class FieldNode implements FieldState<unknown> {
|
||||
readonly structure: FieldNodeStructure;
|
||||
readonly validationState: ValidationState;
|
||||
readonly propertyState: FieldPropertyState;
|
||||
readonly metadataState: FieldMetadataState;
|
||||
readonly nodeState: FieldNodeState;
|
||||
readonly submitState: FieldSubmitState;
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ export class FieldNode implements FieldState<unknown> {
|
|||
this.structure = this.fieldAdapter.createStructure(this, options);
|
||||
this.validationState = this.fieldAdapter.createValidationState(this, options);
|
||||
this.nodeState = this.fieldAdapter.createNodeState(this, options);
|
||||
this.propertyState = new FieldPropertyState(this);
|
||||
this.metadataState = new FieldMetadataState(this);
|
||||
this.submitState = new FieldSubmitState(this);
|
||||
}
|
||||
|
||||
|
|
@ -146,41 +146,41 @@ export class FieldNode implements FieldState<unknown> {
|
|||
return this.nodeState.name;
|
||||
}
|
||||
|
||||
private propertyOrUndefined<M>(prop: AggregateMetadataKey<M, any>): Signal<M> | undefined {
|
||||
return this.hasProperty(prop) ? this.property(prop) : undefined;
|
||||
private metadataOrUndefined<M>(key: AggregateMetadataKey<M, any>): Signal<M> | undefined {
|
||||
return this.hasMetadata(key) ? this.metadata(key) : undefined;
|
||||
}
|
||||
|
||||
get max(): Signal<number | undefined> | undefined {
|
||||
return this.propertyOrUndefined(MAX);
|
||||
return this.metadataOrUndefined(MAX);
|
||||
}
|
||||
|
||||
get maxLength(): Signal<number | undefined> | undefined {
|
||||
return this.propertyOrUndefined(MAX_LENGTH);
|
||||
return this.metadataOrUndefined(MAX_LENGTH);
|
||||
}
|
||||
|
||||
get min(): Signal<number | undefined> | undefined {
|
||||
return this.propertyOrUndefined(MIN);
|
||||
return this.metadataOrUndefined(MIN);
|
||||
}
|
||||
|
||||
get minLength(): Signal<number | undefined> | undefined {
|
||||
return this.propertyOrUndefined(MIN_LENGTH);
|
||||
return this.metadataOrUndefined(MIN_LENGTH);
|
||||
}
|
||||
|
||||
get pattern(): Signal<readonly RegExp[]> | undefined {
|
||||
return this.propertyOrUndefined(PATTERN);
|
||||
return this.metadataOrUndefined(PATTERN);
|
||||
}
|
||||
|
||||
get required(): Signal<boolean> | undefined {
|
||||
return this.propertyOrUndefined(REQUIRED);
|
||||
return this.metadataOrUndefined(REQUIRED);
|
||||
}
|
||||
|
||||
property<M>(prop: AggregateMetadataKey<M, any>): Signal<M>;
|
||||
property<M>(prop: MetadataKey<M>): M | undefined;
|
||||
property<M>(prop: MetadataKey<M> | AggregateMetadataKey<M, any>): Signal<M> | M | undefined {
|
||||
return this.propertyState.get(prop);
|
||||
metadata<M>(key: AggregateMetadataKey<M, any>): Signal<M>;
|
||||
metadata<M>(key: MetadataKey<M>): M | undefined;
|
||||
metadata<M>(key: MetadataKey<M> | AggregateMetadataKey<M, any>): Signal<M> | M | undefined {
|
||||
return this.metadataState.get(key);
|
||||
}
|
||||
hasProperty(prop: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean {
|
||||
return this.propertyState.has(prop);
|
||||
hasMetadata(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean {
|
||||
return this.metadataState.has(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -12,63 +12,59 @@ import type {FieldNode} from './node';
|
|||
import {cast} from './util';
|
||||
|
||||
/**
|
||||
* Tracks custom properties associated with a `FieldNode`.
|
||||
* Tracks custom metadata associated with a `FieldNode`.
|
||||
*/
|
||||
export class FieldPropertyState {
|
||||
/** A map of all `Property` and `AggregateProperty` that have been defined for this field. */
|
||||
private readonly properties = new Map<
|
||||
export class FieldMetadataState {
|
||||
/** A map of all `MetadataKey` and `AggregateMetadataKey` that have been defined for this field. */
|
||||
private readonly metadata = new Map<
|
||||
MetadataKey<unknown> | AggregateMetadataKey<unknown, unknown>,
|
||||
unknown
|
||||
>();
|
||||
|
||||
constructor(private readonly node: FieldNode) {
|
||||
// Field nodes (and thus their property state) are created in a linkedSignal in order to mirror
|
||||
// the structure of the model data. We need to run the property factories untracked so that they
|
||||
// Field nodes (and thus their metadata state) are created in a linkedSignal in order to mirror
|
||||
// the structure of the model data. We need to run the metadata factories untracked so that they
|
||||
// do not cause recomputation of the linkedSignal.
|
||||
untracked(() =>
|
||||
// Property factories are run in the form's injection context so they can create resources
|
||||
// Metadata factories are run in the form's injection context so they can create resources
|
||||
// and inject DI dependencies.
|
||||
runInInjectionContext(this.node.structure.injector, () => {
|
||||
for (const [key, factory] of this.node.logicNode.logic.getMetadataFactoryEntries()) {
|
||||
this.properties.set(key, factory(this.node.context));
|
||||
this.metadata.set(key, factory(this.node.context));
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/** Gets the value of a `Property` or `AggregateProperty` for the field. */
|
||||
get<T>(prop: MetadataKey<T> | AggregateMetadataKey<T, unknown>): T | undefined | Signal<T> {
|
||||
if (prop instanceof MetadataKey) {
|
||||
return this.properties.get(prop) as T | undefined;
|
||||
/** Gets the value of a `MetadataKey` or `AggregateMetadataKey` for the field. */
|
||||
get<T>(key: MetadataKey<T> | AggregateMetadataKey<T, unknown>): T | undefined | Signal<T> {
|
||||
if (key instanceof MetadataKey) {
|
||||
return this.metadata.get(key) as T | undefined;
|
||||
}
|
||||
// Aggregate properties come with an initial value, and are considered to exist for every field.
|
||||
// If no logic explicitly contributes values for the property, it is just considered to be the
|
||||
// initial value. Therefore if the user asks for an aggregate property for a field,
|
||||
// Aggregate metadata comes with an initial value, and are considered to exist for every field.
|
||||
// If no logic explicitly contributes values for the metadata, it is just considered to be the
|
||||
// initial value. Therefore if the user asks for aggregate metadata for a field,
|
||||
// we just create its computed on the fly.
|
||||
cast<AggregateMetadataKey<unknown, unknown>>(prop);
|
||||
if (!this.properties.has(prop)) {
|
||||
const logic = this.node.logicNode.logic.getAggregateMetadata(prop);
|
||||
cast<AggregateMetadataKey<unknown, unknown>>(key);
|
||||
if (!this.metadata.has(key)) {
|
||||
const logic = this.node.logicNode.logic.getAggregateMetadata(key);
|
||||
const result = computed(() => logic.compute(this.node.context));
|
||||
this.properties.set(prop, result);
|
||||
this.metadata.set(key, result);
|
||||
}
|
||||
return this.properties.get(prop)! as Signal<T>;
|
||||
return this.metadata.get(key)! as Signal<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current property state has the given property.
|
||||
* @param prop
|
||||
* @returns
|
||||
*/
|
||||
has(prop: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean {
|
||||
if (prop instanceof AggregateMetadataKey) {
|
||||
// For aggregate properties, they get added to the map lazily, on first access, so we can't
|
||||
// rely on checking presence in the properties map. Instead we check if there is any logic for
|
||||
// the given property.
|
||||
return this.node.logicNode.logic.hasAggregateMetadata(prop);
|
||||
/** Checks whether the current metadata state has the given metadata key. */
|
||||
has(key: MetadataKey<any> | AggregateMetadataKey<any, any>): boolean {
|
||||
if (key instanceof AggregateMetadataKey) {
|
||||
// For aggregate metadata keys, they get added to the map lazily, on first access, so we can't
|
||||
// rely on checking presence in the metadata map. Instead we check if there is any logic for
|
||||
// the given metadata key.
|
||||
return this.node.logicNode.logic.hasAggregateMetadata(key);
|
||||
} else {
|
||||
// Non-aggregate proeprties get added to our properties map on construction, so we can just
|
||||
// Non-aggregate metadata gets added to our metadata map on construction, so we can just
|
||||
// refer to their presence in the map.
|
||||
return this.properties.has(prop);
|
||||
return this.metadata.has(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ describe('max validator', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f.age().property(MAX)()).toBe(5);
|
||||
expect(f.age().metadata(MAX)()).toBe(5);
|
||||
});
|
||||
|
||||
it('merges two maxes preferring the smaller option', () => {
|
||||
|
|
@ -183,7 +183,7 @@ describe('max validator', () => {
|
|||
f.age().value.set(3);
|
||||
expect(f.age().errors()).toEqual([]);
|
||||
|
||||
expect(f.age().property(MAX)()).toBe(5);
|
||||
expect(f.age().metadata(MAX)()).toBe(5);
|
||||
});
|
||||
|
||||
it('merges two maxes _dynamically_ preferring the smaller option', () => {
|
||||
|
|
@ -205,12 +205,12 @@ describe('max validator', () => {
|
|||
f.age().value.set(3);
|
||||
expect(f.age().errors()).toEqual([]);
|
||||
|
||||
expect(f.age().property(MAX)()).toBe(5);
|
||||
expect(f.age().metadata(MAX)()).toBe(5);
|
||||
|
||||
maxSignal.set(2);
|
||||
f.age().value.set(3);
|
||||
expect(f.age().errors()).toEqual([maxError(2, {field: f.age})]);
|
||||
expect(f.age().property(MAX)()).toBe(2);
|
||||
expect(f.age().metadata(MAX)()).toBe(2);
|
||||
});
|
||||
|
||||
it('merges two maxes _dynamically_ ignores undefined', () => {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ describe('maxLength validator', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f.text().property(MAX_LENGTH)()).toBe(5);
|
||||
expect(f.text().metadata(MAX_LENGTH)()).toBe(5);
|
||||
});
|
||||
|
||||
it('merges two maxLengths preferring the smaller option', () => {
|
||||
|
|
@ -182,7 +182,7 @@ describe('maxLength validator', () => {
|
|||
f.text().value.set('abc');
|
||||
expect(f.text().errors()).toEqual([]);
|
||||
|
||||
expect(f.text().property(MAX_LENGTH)()).toBe(5);
|
||||
expect(f.text().metadata(MAX_LENGTH)()).toBe(5);
|
||||
});
|
||||
|
||||
it('merges two maxLengths _dynamically_ preferring the smaller option', () => {
|
||||
|
|
@ -212,7 +212,7 @@ describe('maxLength validator', () => {
|
|||
maxLengthSignal.set(2);
|
||||
|
||||
expect(f.text().errors()).toEqual([maxLengthError(2, {field: f.text})]);
|
||||
expect(f.text().property(MAX_LENGTH)()).toBe(2);
|
||||
expect(f.text().metadata(MAX_LENGTH)()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ describe('min validator', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f.age().property(MIN)()).toBe(5);
|
||||
expect(f.age().metadata(MIN)()).toBe(5);
|
||||
});
|
||||
|
||||
it('merges two mins preferring the larger option', () => {
|
||||
|
|
@ -179,7 +179,7 @@ describe('min validator', () => {
|
|||
f.age().value.set(15);
|
||||
expect(f.age().errors()).toEqual([]);
|
||||
|
||||
expect(f.age().property(MIN)()).toBe(10);
|
||||
expect(f.age().metadata(MIN)()).toBe(10);
|
||||
});
|
||||
|
||||
it('merges two mins _dynamically_ preferring the larger option', () => {
|
||||
|
|
@ -202,7 +202,7 @@ describe('min validator', () => {
|
|||
expect(f.age().errors()).toEqual([]);
|
||||
minSignal.set(30);
|
||||
expect(f.age().errors()).toEqual([minError(30, {field: f.age})]);
|
||||
expect(f.age().property(MIN)()).toBe(30);
|
||||
expect(f.age().metadata(MIN)()).toBe(30);
|
||||
});
|
||||
|
||||
it('merges two mins _dynamically_ ignores undefined', () => {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ describe('minLength validator', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f.text().property(MIN_LENGTH)()).toBe(5);
|
||||
expect(f.text().metadata(MIN_LENGTH)()).toBe(5);
|
||||
});
|
||||
|
||||
it('merges two minLengths preferring the larger option', () => {
|
||||
|
|
@ -182,7 +182,7 @@ describe('minLength validator', () => {
|
|||
f.text().value.set('abcdefghijklmno');
|
||||
expect(f.text().errors()).toEqual([]);
|
||||
|
||||
expect(f.text().property(MIN_LENGTH)()).toBe(10);
|
||||
expect(f.text().metadata(MIN_LENGTH)()).toBe(10);
|
||||
});
|
||||
|
||||
it('merges two minLengths _dynamically_ preferring the larger option', () => {
|
||||
|
|
@ -212,7 +212,7 @@ describe('minLength validator', () => {
|
|||
minLengthSignal.set(20);
|
||||
|
||||
expect(f.text().errors()).toEqual([minLengthError(20, {field: f.text})]);
|
||||
expect(f.text().property(MIN_LENGTH)()).toBe(20);
|
||||
expect(f.text().metadata(MIN_LENGTH)()).toBe(20);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ describe('pattern validator', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f.name().property(PATTERN)()).toEqual([/pir.*jok/]);
|
||||
expect(f.name().metadata(PATTERN)()).toEqual([/pir.*jok/]);
|
||||
});
|
||||
|
||||
it('merges the PATTERN property in an array', () => {
|
||||
|
|
@ -93,7 +93,7 @@ describe('pattern validator', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f.name().property(PATTERN)()).toEqual([/pir.*jok/, /pelmeni/]);
|
||||
expect(f.name().metadata(PATTERN)()).toEqual([/pir.*jok/, /pelmeni/]);
|
||||
});
|
||||
|
||||
it('PATTERN property defaults to empty list', () => {
|
||||
|
|
@ -105,7 +105,7 @@ describe('pattern validator', () => {
|
|||
},
|
||||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
expect(f.name().property(PATTERN)()).toEqual([]);
|
||||
expect(f.name().metadata(PATTERN)()).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -802,12 +802,12 @@ describe('FieldNode', () => {
|
|||
{injector: TestBed.inject(Injector)},
|
||||
);
|
||||
|
||||
expect(f().property(REQUIRED)()).toBe(true);
|
||||
expect(f().metadata(REQUIRED)()).toBe(true);
|
||||
expect(f().valid()).toBe(false);
|
||||
expect(f().readonly()).toBe(false);
|
||||
|
||||
isReadonly.set(true);
|
||||
expect(f().property(REQUIRED)()).toBe(true);
|
||||
expect(f().metadata(REQUIRED)()).toBe(true);
|
||||
expect(f().valid()).toBe(true);
|
||||
expect(f().readonly()).toBe(true);
|
||||
});
|
||||
|
|
@ -877,13 +877,13 @@ describe('FieldNode', () => {
|
|||
|
||||
expect(f.first().errors()).toEqual([requiredError({field: f.first})]);
|
||||
expect(f.first().valid()).toBe(false);
|
||||
expect(f.first().property(REQUIRED)()).toBe(true);
|
||||
expect(f.first().metadata(REQUIRED)()).toBe(true);
|
||||
|
||||
f.first().value.set('Bob');
|
||||
|
||||
expect(f.first().errors()).toEqual([]);
|
||||
expect(f.first().valid()).toBe(true);
|
||||
expect(f.first().property(REQUIRED)()).toBe(true);
|
||||
expect(f.first().metadata(REQUIRED)()).toBe(true);
|
||||
});
|
||||
|
||||
it('should validate conditionally required field', () => {
|
||||
|
|
@ -899,19 +899,19 @@ describe('FieldNode', () => {
|
|||
|
||||
expect(f.first().errors()).toEqual([]);
|
||||
expect(f.first().valid()).toBe(true);
|
||||
expect(f.first().property(REQUIRED)()).toBe(false);
|
||||
expect(f.first().metadata(REQUIRED)()).toBe(false);
|
||||
|
||||
f.last().value.set('Loblaw');
|
||||
|
||||
expect(f.first().errors()).toEqual([requiredError({field: f.first})]);
|
||||
expect(f.first().valid()).toBe(false);
|
||||
expect(f.first().property(REQUIRED)()).toBe(true);
|
||||
expect(f.first().metadata(REQUIRED)()).toBe(true);
|
||||
|
||||
f.first().value.set('Bob');
|
||||
|
||||
expect(f.first().errors()).toEqual([]);
|
||||
expect(f.first().valid()).toBe(true);
|
||||
expect(f.first().property(REQUIRED)()).toBe(true);
|
||||
expect(f.first().metadata(REQUIRED)()).toBe(true);
|
||||
});
|
||||
|
||||
it('should link required error messages to their predicate', () => {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ describe('resources', () => {
|
|||
});
|
||||
|
||||
validate(p.name, ({state}) => {
|
||||
const remote = state.property(RES)!;
|
||||
const remote = state.metadata(RES)!;
|
||||
if (remote.hasValue()) {
|
||||
return customError({message: remote.value()});
|
||||
} else {
|
||||
|
|
@ -106,7 +106,7 @@ describe('resources', () => {
|
|||
});
|
||||
|
||||
validate(p.name, ({state}) => {
|
||||
const remote = state.property(RES)!;
|
||||
const remote = state.metadata(RES)!;
|
||||
if (remote.hasValue()) {
|
||||
return customError({message: remote.value()});
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue