【问题标题】:How to get two way databindings working in blazor?如何让两种方式的数据绑定在 blazor 中工作?
【发布时间】:2021-02-01 17:37:38
【问题描述】:

我有以下类似于TextBox 组件的组件。但是由于某种原因,Value 的内容似乎从未改变。

我希望这可以在没有手动 JavaScript 的情况下与数据绑定一起使用,不是吗?


<div class="form-group">
    <input type="text" class="form-control" @bind="Value" @onkeyup="OnKeyUp" placeholder="@Placeholder"/>
</div>

@code {
    
    [Parameter]
    public string Value { get; set; }

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

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

    private void OnKeyUp(KeyboardEventArgs obj)
    {
        ValueChanged.InvokeAsync(Value);
    }

}

【问题讨论】:

    标签: blazor blazor-server-side


    【解决方案1】:

    您不应绑定到 [Parameter],因为它可能会导致副作用 (see Steve Sanderson's comment here)

    您似乎希望对每个更改进行两种绑定,为此我会使用oninput 而不是onkeyup,但如果您确实需要,您可以使用onkeyup

    主要是绑定到本地,永远不要手动更改公共参数:

    <div class="form-group">
        <input type="text" class="form-control" 
               @bind-value=@InternalValue 
               @bind-value:event="oninput" 
               placeholder="@Placeholder"/>
    </div>
    
    @code {
    
        string InternalValue
        {
            get => Value;
            set 
            {
                if (value!=Value)
                {
                    ValueChanged.InvokeAsync(value);        
                }
            }
        }
    
        [Parameter]
        public string Value { get; set; }
    
        [Parameter]
        public EventCallback<string> ValueChanged { get; set; }
    
        [Parameter]
        public string Placeholder { get; set; }
    }
    

    编辑:添加史蒂夫·桑德森的笔记以防它们消失...

    Steve Sanderson 引用上面链接的 GitHub 问题:

    好的,我已经更详细地查看了,看看发生了什么。有一个 下面的解释,但在此之前,我将重申我的主张 核心问题是子组件覆盖了自己的 [参数] 属性值。通过避免这样做,您可以避免这种情况 问题。

    在这种情况下以及在其他情况下,Blazor 依赖于父对子 参数分配是安全的(不覆盖你想要的信息 保持)并且没有副作用,例如触发更多渲染 (因为那样你可能会陷入无限循环)。我们大概应该 加强文档中的指导,而不仅仅是说“不要写信给你的 自己的参数”并扩展它以警告不要产生副作用 在这样的属性设置器中。 Blazor 使用 C# 属性来表示 从父组件到子组件的通信通道很漂亮 方便开发人员并且在源代码中看起来不错,但是 副作用的能力是有问题的。我们已经有一个 编译时分析器,如果你没有正确的警告 [Parameter] 属性上的可访问性修饰符 - 也许我们应该 如果参数是其他参数,则扩展它以给出警告/错误 比简单的 { get;放; } 自动属性。

    所以在这种情况下,解决方案非常简单:替换 Component1 的 具有简单 { get; 的值属性放;一个,而不是 试图写入它,让 Component1 响应按钮点击 触发 ValueChanged。然后你没有任何递归渲染 循环,不会发生数据覆盖。

    private void DecrementValue()
    {
        //Value--; <-- Don't do this
    
        // Do this instead:
        ValueChanged.InvokeAsync(Value - 1);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-11
      • 2020-04-11
      • 2016-02-27
      • 2020-02-15
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多