runceel / ReactiveProperty

ReactiveProperty provides MVVM and asynchronous support features under Reactive Extensions. Target frameworks are .NET 6+, .NET Framework 4.7.2 and .NET Standard 2.0.
MIT License
899 stars 101 forks source link

ReactivePropertiesValidator で ICollection でもバリデーションできないでしょうか #493

Open smasanor opened 1 week ago

smasanor commented 1 week ago

ICollection<IReactiveProperty>やICollection<ValidatableReactiveProperty>のような形でもバリデーションしたいです

runceel commented 1 week ago

EditContextEditFormModel プロパティに設定しているオブジェクトが以下のようになっているということですか?

class SomeModel
{
  public ICollection<ValidatableReactiveProperty<string>> SomeValues { get; set; }
}

そして、こんな感じでフォームで使っているという理解であっていますか?

<EditForm Model="_someModel" ...>
    ...
    @foreach (var p in _someValues)
    {
        <InputText @bind-Value="p.Value" />
    }
</EditForm>

@code {
  private SomeModel _someModel = new();
}
smasanor commented 1 week ago

回答ありがとうございます 例示も環境もなく、失礼しました Blazor でした ほぼご指摘通りですがご指摘の内容に沿って例示します

class SomeModel
{
    public ICollection<SomeEntity> SomeValues { get; set; }
}

class SomeEntity
{
    ValidatableReactiveProperty<string> vrpA { get; set; }
    ValidatableReactiveProperty<string?> vrpB { get; set; }
}

<FluentEditForm Model="_someModel" ...>
    <ReactivePropertiesValidator />
    <OreoreValidationSummary />

    <FluentDataGrid Items="_someModel.SomeValues" ...>
        <PropertyColumn>
            <FluentTextField @bind-Value="@context.vrpA.Value" />
        </PropertyColumn>
        <PropertyColumn>
            <FluentTextField @bind-Value="@context.vrpB.Value" />
        </PropertyColumn>
    </FluentDataGrid>
</EditForm>

@code {
  private SomeModel _someModel = new();
}

UI には FluentUI を使っています FluentDataGrid の IQueryable Items へ渡したコレクションの中の SomeEntity クラス内の ValidatableReactiveProperty が ReactivePropertiesValidator のバリデーションの対象になってほしいです ReactivePropertiesValidatorEditContextExtensions.EnableReactivePropertiesValidation を見たらモデルに直接あるプロパティだけでコレクションは対象外のように見えました バリデーションした結果の ValidationMessageStore は OreoreValidationSummary で参照できていました

やりたいこと

現状は FluentDataGrid の列を一つにして ValidatableReactiveProperty をコンポーネントにまとめてその中でも FluentEditForm と ReactivePropertiesValidator をつけることでエラー時に赤枠がつくようにしています 全体として EditForm が一つになったほうがスマートな構成になると思って書き込みました

runceel commented 5 days ago

任意の構造を持ったオブジェクトに対してバリデーションをさせるのは、汎用部品として用意するときりがない (コレクション内の要素のオブジェクトがさらにプロパティを持っていて、その中がコレクションだったら等) と思うので、以下のサンプルのように自分でカスタムの処理を書いた方が楽だと思います。

https://github.com/runceel/NestedRPObjValidationSample

このリポジトリを Clone して実行するとページに SomeValues に 3 件のデータを持たせた状態のフォームが表示されます。 送信ボタンを押すとバリデーションが走ります。Addボタンを押すとSomeValuesに要素を追加します。

runceel commented 5 days ago

このサンプルだと ValidationSummary が何故か表示されないですね…。 EditContext の GetValidationMessages() でメッセージをとって表示すれば表示はされるのですが、それは ValidationSummary の実装と同じ処理のはずなのですが…。

smasanor commented 5 days ago

わざわざサンプルを作成していただいてありがとうございます サンプルを参考に実装してみます DataAnnotationsValidator を追加したら ValidationSummary が表示されるようになりました