自定义组件上的 Blazor 双向绑定 [英] Blazor TwoWay Binding on custom Component

查看:152
本文介绍了自定义组件上的 Blazor 双向绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 blazor 服务器端应用程序,但在两个自定义组件之间绑定值时遇到问题.

我已经查看了有关 bind 或 @bind 应该如何工作的不同示例,但我无法弄清楚有关此事的最新信息是什么.

给定一个模型类用户:

公共类用户{[映射(列名 =short_id")]公共字符串 ShortId { 获取;放;}公共用户(){}}

我想构建一个表单,显示该用户的所有属性,并将它们包含在输入中,以便对其进行编辑并最终保存到数据库中.

我的表单(父组件)如下所示:

<AnimatedUserInput TbText="@User.ShortId" Placeholder="MHTEE Id"/><button class="btn btn-secondary" @onclick="Hide" style="{display:inline-block;}">返回</button><button class="btn btn-primary" @onclick="SaveUser" style="{display:inline-block;}">保存</button>

@代码 {[参数] public vUser User { get;放;}[参数] public Action Hide { get;放;}bool _error = false;无效保存用户(){验证用户数据();}无效验证用户数据(){_error = string.IsNullOrWhiteSpace(User.ShortId);}}

其中 AnimatedUserInput 是一个自定义组件,如下所示:

<input type="text" @bind="@TbText"/><span data-placeholder="@Placeholder"></span>

@代码 {[范围]公共字符串 TbText { 获取;放;}[范围]公共字符串占位符{获取;放;}}

现在在输入文本框中,我正确地看到了父组件中 User 对象的 ShortId.

但是,如果我更改输入中的文本并单击 Save 按钮,该按钮会触发 ValidateUserData 方法并允许我查看当前的 User 对象 我看到在实际的 User.ShortId 属性中没有进行任何更改,但仅对输入进行了更改.

有没有办法绑定它,以便输入中的更改会自动应用于绑定的属性?

我有几个这些属性需要在表单中显示,这就是为什么我不想为每个属性挂钩自定义 OnChanged 事件.

解决方案

对于任何遇到此问题的人来说都可以.我尝试了更多并找到了解决方案.因此,对于我的自定义输入组件 AnimatedUserInput,我添加了一个 EventCallback,每次更新输入值时都会调用它:

@code {[范围]公共字符串 TbText{得到 =>_tbText;放{如果(_tbText == 值)返回;_tbText = 值;TbTextChanged.InvokeAsync(value);}}[范围]公共 EventCallbackTbTextChanged { 获取;放;}[范围]公共字符串占位符{获取;放;}私有字符串_tbText;}

我的父组件上的绑定看起来像这样:

<AnimatedUserInput @bind-TbText="@User.ShortId" Placeholder="MHTEE Id"/><AnimatedUserInput @bind-TbText="@User.FirstName" Placeholder="名字"/><AnimatedUserInput @bind-TbText="@User.LastName" Placeholder="Last name"/><AnimatedUserInput @bind-TbText="@User.UserName" Placeholder="用户名"/><AnimatedUserInput @bind-TbText="@User.StaffType" Placeholder="员工类型"/><AnimatedUserInput @bind-TbText="@User.Token" Placeholder="Token"/><button class="btn btn-secondary" @onclick="Hide" style="{display:inline-block;}">返回</button><button class="btn btn-primary" @onclick="SaveUser" style="{display:inline-block;}">保存</button>

@代码 {[参数] public vUser User { get;放;}}

这种方式 blazor 可以正确地将值绑定在一起,并按照我希望它们绑定的方式从两侧更新它们.

I'm creating a blazor server side app and have problems to bind a value between two custom components.

I've looked through different example of how the bind or @bind is supposed to work but I cannot figure out what up to date information on this matter is.

Given a model class User:

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

        public User()
        {

        }
    }

I want to build a form which displays all properties of this user and has them in an input so it can be edited and in the end saved to a database.

My Form (parent component) looks like this:

<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);
    }
}

Where AnimatedUserInput is a custom component that looks like this:

<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; }
}

Now in the Input textbox I correctly see the ShortId of the User object in my parent component.

However if I change the text in the input and click on the Save button which triggers the ValidateUserData method and allows me to look at the current User object I see that no changes have been done in the actual User.ShortId property but only on the input.

Is there any way to bind it so that changes in the input will automatically be applied to the binded property?

I have several of these properies which need to be shown in the form which is why I dont want to hook a custom OnChanged Event for each of those properties.

解决方案

Ok so for anyone stumbling upon this. I tried a bit more and found a solution. So to my custom input component AnimatedUserInput I added a EventCallback which I call everytime the value on the input is updated:

@code {

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

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

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

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

    private string _tbText;
}

And the binding on my parent component looks like this:

<div class="edit-user-form">
    <AnimatedUserInput @bind-TbText="@User.ShortId" Placeholder="MHTEE Id"/>
    <AnimatedUserInput @bind-TbText="@User.FirstName" Placeholder="First name" />
    <AnimatedUserInput @bind-TbText="@User.LastName" Placeholder="Last name" />
    <AnimatedUserInput @bind-TbText="@User.UserName" Placeholder="Username" />
    <AnimatedUserInput @bind-TbText="@User.StaffType" Placeholder="Staff type" />
    <AnimatedUserInput @bind-TbText="@User.Token" Placeholder="Token" />
    <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; }
}

This way blazor can correctly bind the values together and updates them from both sides the way I would expect them to bind.

这篇关于自定义组件上的 Blazor 双向绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆