Skip to content

Caso de uso: opciones dependientes ​

Anterior: formulario · Casos de uso · Siguiente: reutilización

Usa Options cuando las opciones de un campo dependen de otro valor, como ciudades por país. La sesión carga datos y descarta respuestas antiguas; la UI decide qué hacer con la selección actual.

Flujo ​

text
CountryId cambia
    ↓ EnsureLoadedAsync
    ↓ compara DependsOn + contexto
    ├─ sin cambios → reutiliza carga
    └─ con cambios → cancela carga anterior
                       ↓ consulta ciudades
                       ↓ Ready / Failed / Canceled

Ejemplo completo ​

csharp
using Greencore.platform.validators;

var definition = Options.For<AddressDraft, AddressContext>()
    .Field(x => x.CityId)
    .Load<CityOption>((address, context, token) =>
        context.Cities.GetByCountryAsync(address.CountryId, token))
    .DependsOn(x => x.CountryId);

using var session = definition.CreateSession();

session.Changed += snapshot =>
{
    if (snapshot.State == DataState.Ready)
        Console.WriteLine($"Opciones publicadas: {snapshot.Value!.Count}");
};

var address = new AddressDraft(CountryId: 1, CityId: null);
var context = new AddressContext(new CityRepository());

var first = await session.EnsureLoadedAsync(address, context);
foreach (var city in first.Value!)
    Console.WriteLine(city.Name);

// Mismas dependencias y contexto: reutiliza la operación anterior.
var reused = await session.EnsureLoadedAsync(address with { CityId = 10 }, context);

// Fuerza una consulta aunque las dependencias no hayan cambiado.
var refreshed = await session.ReloadAsync(address, context);

public sealed record AddressDraft(int CountryId, int? CityId);
public sealed record CityOption(int Id, string Name);
public sealed record AddressContext(ICityRepository Cities);

public interface ICityRepository
{
    ValueTask<IReadOnlyList<CityOption>> GetByCountryAsync(int countryId, CancellationToken cancellationToken);
}

public sealed class CityRepository : ICityRepository
{
    public ValueTask<IReadOnlyList<CityOption>> GetByCountryAsync(int countryId, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();
        IReadOnlyList<CityOption> result = countryId == 1
            ? [new(10, "La Paz"), new(11, "Cochabamba")]
            : [new(20, "Lima")];
        return ValueTask.FromResult(result);
    }
}

Decisiones importantes ​

  • DependsOn compara valores; no se suscribe a cambios del modelo.
  • Declara toda propiedad que afecte al loader.
  • EnsureLoadedAsync reutiliza cargas equivalentes.
  • ReloadAsync fuerza una nueva carga.
  • Un fallo permite reintentar.
  • Durante Pending no se conservan opciones antiguas.
  • La sesión no borra CityId; esa decisión pertenece a la UI.
  • Un plan de validación debe comprobar por separado que la ciudad seleccionada sea válida.

Uso personal limitado. Uso comercial sujeto a autorización escrita.