angular / angular/angular

Enable dynamic schema composition based on form state

Ouverte
#67,071 4 commentaires 3 réactions 0 personnes assignées Voir sur GitHub
area: forms forms: signals
Langage dominant
TypeScript
Étoiles
101k
Forks
27.5k
Merge moyen
1 j 19 h
PR mergées (30 j)
288

Description

### Which @angular/* package(s) are relevant/related to the feature request?

_No response_

---

### Description

I have a form with different properties.

```ts
export interface Field {
fieldName: string;
fieldType?: string;
fieldRequired?: boolean;
fieldMaxSize?: number;
fieldVisible?: boolean;
}

export interface FieldConfig {
fields: Field[];
}

export interface Order {
label: string;
// ...
}

export interface ActivityType {
label: string;
fieldConfig: FieldConfig;
}

export function fieldConfigSchema(fieldConfig: FieldConfig) {
return schema(path => {
for (const field of fieldConfig.fields) {
required(path[field.fieldName], { when: () => field.fieldRequired });
hidden(path[field.fieldName], () => !field.fieldVisible);
maxLength(path[field.fieldName], () => field.fieldMaxSize);
}
});
}

export interface FormModel {
user: User;
activityType: ActivityType;
order: Order;
}
```

The form is defined as follows:

```ts
formModel = signal({
user: null,
activityType: null,
order: null
});

form = form(this.formModel, path => {
applyWhen(
path.order,
context => !!context.valueOf(path.activityType)?.fieldConfig,
fieldConfigSchema(
/* value of fieldConfig from activityType not available here */
)
);
});
```

The issue is that `fieldConfigSchema` needs access to the `fieldConfig`
coming from the selected `activityType`, but that value is only available
through the form context.

---

### Proposed solution

Allow building a schema dynamically based on the form context:

```ts
applyWhen(
path.order,
context => !!context.valueOf(path.activityType)?.fieldConfig,
context =>
fieldConfigSchema(
context.valueOf(path.activityType).fieldConfig
)
);
```

This would allow the schema to be constructed using runtime values from
the form context.

---

### Alternatives considered

```ts
export function fieldConfigSchema(fieldConfig: Signal) {
return schema(path => {
for (const field of fieldConfig().fields) {
required(path[field.fieldName], { when: () => field.fieldRequired });
hidden(path[field.fieldName], () => !field.fieldVisible);
maxLength(path[field.fieldName], () => field.fieldMaxSize);
}
});
}

form = form(this.formModel, path => {
applyWhen(
path.order,
context => !!context.valueOf(path.activityType)?.fieldConfig,
fieldConfigSchema(this.fieldConfig)
);
});
fieldConfig = computed(() => this.form.activityType().value()?.fieldConfig);
```

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Commencez par suivre les API form, applyWhen, schema et context.valueOf afin de comprendre comment les schémas sont actuellement construits et quand le contexte de form est disponible. Le travail est terminé lorsqu’un schéma peut être construit à partir du contexte de form à l’exécution, avec une couverture pour l’exemple activityType fieldConfig et en préservant le comportement existant.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
angular, typescript
Domaine
frontend
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.