ReactivePropertiesValidator で ICollection でもバリデーションできないでしょうか
ICollection<IReactiveProperty<T>>やICollection<ValidatableReactiveProperty<T>>のような形でもバリデーションしたいです
EditContext や EditForm の Model プロパティに設定しているオブジェクトが以下のようになっているということですか?
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();
}
回答ありがとうございます 例示も環境もなく、失礼しました 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<SomeEntity> Items へ渡したコレクションの中の SomeEntity クラス内の ValidatableReactiveProperty が ReactivePropertiesValidator のバリデーションの対象になってほしいです ReactivePropertiesValidatorEditContextExtensions.EnableReactivePropertiesValidation を見たらモデルに直接あるプロパティだけでコレクションは対象外のように見えました バリデーションした結果の ValidationMessageStore は OreoreValidationSummary で参照できていました
やりたいこと
- エラー時に赤枠がついてほしい モデル側で ValidatableReactiveProperty を監視してエラーを行番号で表示できればいいと思っていましたが、どこがエラーの行かわかりにくかったため EditForm を使ってエラーの項目に自動で赤枠がつくようにしたいです
- UI だけでエラーを表示したい ICollection<SomeEntity> も ReactivePropertiesValidator の対象になればモデルで監視している処理でエラーチェックしなくても UI だけでエラーを表現できると思っています
現状は FluentDataGrid の列を一つにして ValidatableReactiveProperty をコンポーネントにまとめてその中でも FluentEditForm と ReactivePropertiesValidator をつけることでエラー時に赤枠がつくようにしています 全体として EditForm が一つになったほうがスマートな構成になると思って書き込みました
任意の構造を持ったオブジェクトに対してバリデーションをさせるのは、汎用部品として用意するときりがない (コレクション内の要素のオブジェクトがさらにプロパティを持っていて、その中がコレクションだったら等) と思うので、以下のサンプルのように自分でカスタムの処理を書いた方が楽だと思います。
https://github.com/runceel/NestedRPObjValidationSample
このリポジトリを Clone して実行するとページに SomeValues に 3 件のデータを持たせた状態のフォームが表示されます。
送信ボタンを押すとバリデーションが走ります。Addボタンを押すとSomeValuesに要素を追加します。
このサンプルだと ValidationSummary が何故か表示されないですね…。
EditContext の GetValidationMessages() でメッセージをとって表示すれば表示はされるのですが、それは ValidationSummary の実装と同じ処理のはずなのですが…。
わざわざサンプルを作成していただいてありがとうございます サンプルを参考に実装してみます DataAnnotationsValidator を追加したら ValidationSummary が表示されるようになりました
EditContext の NotifyValidationStateChanged を呼び出すことで ValidationSummary に表示されるようになりました。
DataAnnotationsValidator は不要になります。
private void ValidationRequested(object? sender, ValidationRequestedEventArgs args)
{
Verify.ThrowIfNull(_editContext);
Verify.ThrowIfNull(_validationMessageStore);
_validationMessageStore.Clear();
foreach (var someValue in _model.SomeValues)
{
someValue.Validate();
AddErrorIfHasError(someValue.A);
AddErrorIfHasError(someValue.B);
}
_editContext.NotifyValidationStateChanged(); // これを追加
StateHasChanged();
}
調査してもらってありがとうございます DataAnnotationsValidator は必須だと思っていこんでいましたが、AddErrorIfHasError()があるのでなくてもエラーを設定できるんですね
DataAnnotationsValidator は内部で DataAnnotations 使ってバリデーションしてエラーを Add して NotifyValidationStateChanged とかを呼んでいるだけなので同じことをしてあげればエラーは表示されるようになります。
ありがとうございました!