15

blazor サーバー側アプリを作成していますが、2 つのカスタム コンポーネント間で値をバインドする際に問題があります。

bind または @bind がどのように機能するかのさまざまな例を調べましたが、この問題に関する最新情報が何であるかわかりません。

モデル クラス User が与えられた場合:

public class User
    {
        [Mapping(ColumnName = "short_id")]
        public string ShortId { get; set; }

        public User()
        {

        }
    }

このユーザーのすべてのプロパティを表示し、それらを入力に含めるフォームを作成して、編集して最終的にデータベースに保存できるようにしたいと考えています。

私のフォーム(親コンポーネント)は次のようになります。

<div class="edit-user-form">
    <AnimatedUserInput TbText="@User.ShortId" Placeholder="MHTEE Id"/>
    <button class="btn btn-secondary" @onclick="Hide" style="{display:inline-block;}">Back</button>
    <button class="btn btn-primary" @onclick="SaveUser" style="{display:inline-block;}">Save</button>
</div>
@code {
    [Parameter] public vUser User { get; set; }

    [Parameter] public Action Hide { get; set; }

    bool _error = false;

    void SaveUser()
    {
        ValidateUserData();
    }

    void ValidateUserData()
    {
        _error = string.IsNullOrWhiteSpace(User.ShortId);
    }
}

AnimatedUserInput次のようなカスタム コンポーネントはどこにありますか。

<div class="edit-area @FocusClass @WiggleClass">
    <input type="text" @bind="@TbText" />
    <span data-placeholder="@Placeholder"></span>
</div>
@code {
    [Parameter]
    public string TbText { get; set; }

    [Parameter]
    public string Placeholder { get; set; }
}

入力テキストボックスに、親コンポーネントShortIdのオブジェクトが正しく表示されます。User

ただし、入力のテキストを変更し、メソッドSaveをトリガーして現在のオブジェクトを表示できるボタンをクリックすると、実際のプロパティでは変更が行われておらず、入力のみが変更されていることがわかります。ValidateUserDataUserUser.ShortId

入力の変更がバインドされたプロパティに自動的に適用されるようにバインドする方法はありますか?

OnChangedフォームに表示する必要があるこれらのプロパティがいくつかあるため、これらのプロパティごとにカスタム イベントをフックしたくないのです。

4

4 に答える 4

1

これは私が双方向バインディングを達成した方法です

親コンポーネント

<LabelledField Class=""
   Label="Label value"
   DateValue="@Model.Value"
   OnDateChange="@((e) => Model.Value = e )"
   Type="InputType.date" />

子コンポーネント

<div class="@Class">
<div class="ft-07 mb-03 field-label @LabelClass">@Label</div>
@switch (Type)
{
    case InputType.constant:
        <div class="label-field-value @ValueClass">@Value</div>
        break;
    case InputType.text:
        <input class="form-control input @ValueClass"
               type="text"
               @bind="Value" />

        break;
    case InputType.date:
        <input class="form-control input @ValueClass"
               type="date"
               @bind="DateValue" />

        break;
    default:
        break;
}
@code{
private string _tbText;
private DateTime? _tbDate;

[Parameter]
public string Class { get; set; }

[Parameter]
public string Label { get; set; }

[Parameter]
public string LabelClass { get; set; }

[Parameter]
public string Value
{
    get => _tbText;
    set
    {
        if (_tbText == value) return;

        _tbText = value;
        OnTextChange.InvokeAsync(value);
    }
}

[Parameter]
public DateTime? DateValue
{
    get => _tbDate;
    set
    {
        if (_tbDate == value) return;

        _tbDate = value;
        OnDateChange.InvokeAsync(_tbDate);
    }
}

[Parameter]
public string ValueClass { get; set; }

[Parameter]
public InputType Type { get; set; } = InputType.constant;

[Parameter]
public EventCallback<string> OnTextChange { get; set; }

[Parameter]
public EventCallback<DateTime?> OnDateChange { get; set; }
}
于 2021-04-13T17:10:03.680 に答える