Summary
The current IFieldDependency<TModel> interface only supports synchronous OnDependencyChanged() callbacks. This prevents lookup and autocomplete fields from refreshing their options asynchronously when a parent field changes (e.g., selecting a Country should trigger an async API call to fetch Cities).
This was identified as Phase C during the implementation of #27 (lookup fields).
Problem
// Current interface — synchronous only
public interface IFieldDependency<TModel>
{
string DependentFieldName { get; }
void OnDependencyChanged(TModel model); // ← sync
}
When a parent field changes, OnDependencyChanged is called synchronously. This means:
- Cannot call async APIs to refresh child field options
- Cannot show loading states during option refresh
- Cannot cancel in-flight requests when the parent changes again
Proposed Solution
1. Add IAsyncFieldDependency<TModel> interface
public interface IAsyncFieldDependency<TModel> : IFieldDependency<TModel>
{
Task OnDependencyChangedAsync(TModel model, CancellationToken cancellationToken = default);
}
2. Extend DependsOn() with async overload
// New async overload
.AddField(x => x.City)
.DependsOn(x => x.Country, async (model, country, ct) =>
{
var cities = await cityApi.GetByCountryAsync(country, ct);
// update options...
})
3. Add WithCascadingFilter convenience method
.AddField(x => x.City)
.AsAutocomplete(cityProvider)
.WithCascadingFilter<string>(
parentField: x => x.Country,
filterProvider: (country, ct) => cityProvider.WithFilter("country", country))
4. Update rendering pipeline
FormCraftComponent must detect IAsyncFieldDependency and await the async callback
- Show a loading indicator on the child field while options are refreshing
- Support
CancellationToken to cancel stale requests
Acceptance Criteria
Context
Summary
The current
IFieldDependency<TModel>interface only supports synchronousOnDependencyChanged()callbacks. This prevents lookup and autocomplete fields from refreshing their options asynchronously when a parent field changes (e.g., selecting a Country should trigger an async API call to fetch Cities).This was identified as Phase C during the implementation of #27 (lookup fields).
Problem
When a parent field changes,
OnDependencyChangedis called synchronously. This means:Proposed Solution
1. Add
IAsyncFieldDependency<TModel>interface2. Extend
DependsOn()with async overload3. Add
WithCascadingFilterconvenience method4. Update rendering pipeline
FormCraftComponentmust detectIAsyncFieldDependencyand await the async callbackCancellationTokento cancel stale requestsAcceptance Criteria
IAsyncFieldDependency<TModel>interface added to core abstractionsDependsOn()has an async overload acceptingFunc<TModel, TDependsOn, CancellationToken, Task>FormCraftComponenthandles async dependency refresh with loading stateDependsOn()continues to work unchanged (backward compatible)AsAutocomplete()andAsLookup()from Feature Request : Lookup fields interface over cascaded drop down (e.g country and city) #27Context
FormCraft/Forms/Core/FieldDependency.cs,FormCraft/Forms/Builders/FieldBuilder.cs,FormCraft.ForMudBlazor/Features/FormContainer/FormCraftComponent.razor.cs