-
Notifications
You must be signed in to change notification settings - Fork 31
Open
Description
Description:
Hello! Thank you for the excellent work on reactive_forms_generator. I've found it incredibly valuable for most form scenarios, but I'm encountering significant limitations when working with recursive form structures.
The Problem: Recursive Form Models
Many real-world applications require forms with recursive relationships where a model contains instances of itself. Common examples include:
- Survey/questionnaire builders (questions containing sub-questions)
- Comment systems (comments with nested replies)
- Organizational charts (employees managing other employees)
- File systems (folders containing subfolders)
- Rule engines (rules containing nested rules)
Current Limitation Example:
Consider this simple recursive model:
dart
class TreeNode {
final String label;
final List<TreeNode> children; // Recursive relationship
TreeNode({required this.label, this.children = const []});
}
With the current generator, I cannot properly generate form structures for this model because:
- Infinite Recursion Risk: The generator cannot handle the circular dependency during code generation
- No Nested FormArray Support: There's no way to generate FormArray where each FormGroup represents another instance of the same recursive structure
- Missing Recursive Validation: Validation that needs to traverse the entire tree structure isn't supported
Current Workaround - Manual Implementation:
I'm forced to implement the entire form structure manually:
dart
// Manual form creation for recursive structure
FormGroup createTreeNodeForm(TreeNode? node) {
return FormGroup({
'label': FormControl<String>(value: node?.label, validators: [Validators.required]),
'children': FormArray<Map<String, dynamic>>(
node?.children.map((child) => createTreeNodeForm(child)).toList() ?? [],
validators: [/* Complex recursive validation */]
),
});
}
// Manual validator for recursive structure
class TreeNodeValidator extends Validator<dynamic> {
@override
Map<String, dynamic>? validate(AbstractControl<dynamic> control) {
if (control is! FormGroup) return null;
final errors = <String, dynamic>{};
final labelControl = control.control('label');
final childrenControl = control.control('children');
// Validate current node
if (labelControl.value == null) {
errors['label'] = {'required': true};
}
// Recursively validate children
if (childrenControl is FormArray) {
final childrenErrors = <int, Map<String, dynamic>>{};
for (int i = 0; i < childrenControl.controls.length; i++) {
final childErrors = validate(childrenControl.controls[i]);
if (childErrors != null) {
childrenErrors[i] = childErrors;
}
}
if (childrenErrors.isNotEmpty) {
errors['children'] = childrenErrors;
}
}
return errors.isEmpty ? null : errors;
}
}
Requested Features:
- Recursive Model Annotation
- A way to annotate recursive relationships to guide code generation
- Example: @recursivefield() or @NestedForm() annotation
- Automatic FormArray Generation
- Generate proper FormArray for recursive list fields
- Handle the circular dependency during code generation
- Recursive Validation Support
- Generate validators that can traverse recursive structures
- Support for depth limits or other recursion constraints
- Helper Methods for Dynamic Operations
- Generated methods for adding/removing nested recursive elements
- Type-safe ways to manipulate the recursive form structure
Expected Usage:
dart
// Ideal future usage with enhanced generator support
@ReactiveForm()
class TreeNode {
@ReactiveControl(validators: [RequiredValidator()])
final String label;
@RecursiveField() // New annotation for recursive relationships
final List<TreeNode> children;
TreeNode({required this.label, this.children = const []});
}
// Generated code would handle the recursive form creation and validation
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels