Blazor 中两个子组件的双向绑定通信

问题描述 投票:0回答:1

我在使用 Blazor WASM 的应用程序中遇到了双向绑定的一些问题。 我正在尝试在具有相同父组件的两个子组件之间传递一个值。

当我调用一个函数来更新我的属性时:

public async Task MyFunction()
{
    FirstChildInputChanged.InvokeAsync(FirstChildInput);
}

它完美地工作。

但是当我试图将其放入属性集中时:

private string _firstChildInput;

[Parameter]
public string FirstChildInput
{
    get { return _firstChildInput; }
    set { _firstChildInput = value;
        FirstChildInputChanged.InvokeAsync(value);
    }
}

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

什么都行不通。当我开始输入我的输入时,我的应用程序开始冻结,就像它正在等待响应一样。

-------------------------------------------- ----------------------------------------------

这是我的代码:

父组件

@page "/counter"

<PageTitle>Component Page</PageTitle>


<div>
    <br : />
    <div style="display: flex; justify-content:center; font-weight: bold;"><h1>Vous vous trouvez dans le composant Parent</h1></div>
    <br />
    <br />
    <br />
    <div style="display: flex; justify-content: space-evenly">
        <FirstChildComponent  @bind-FirstChildInput="_valueToPass"/>
        <SecondChildComponent @bind-SecondChildInput="_valueToPass" />
    </div>
</div>


@code {
    private string _valueToPass { get; set; }
}

第一个子组件

<div style="display: flex; flex-direction: column; align-items: center; height: 200px; width: 400px; border: solid 1px black; padding:16px">
    <h3>FirstChildComponent</h3>
    <br />

    <div style="display: flex; flex-direction: column">
        <input style="height: 32px;" @bind-value="@FirstChildInput" @bind-value:event="oninput" />
        <br/>
        <span>
            <label>Résultat : @_firstChildInput</label>
        </span>
    </div>

</div>

@code {
    private string _firstChildInput;

    [Parameter]
    public string FirstChildInput
    {
        get { return _firstChildInput; }
        set { _firstChildInput = value;
            FirstChildInputChanged.InvokeAsync(value);
        }
    }

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

第二个子组件

<div style="display: flex; flex-direction: column; align-items: center; height: 200px; width: 400px; border: solid 1px black; padding:16px">
    <h3>SecondChildComponent</h3>
    <br />

    <div style="display: flex; flex-direction: column">
        <input style="height: 32px;" @bind-value="@SecondChildInput" @bind-value:event="oninput"/>
        <br/>
        <span>
            <label>Résultat : @_secondChildInput</label>
        </span>
    </div>

</div>

@code {
    private string _secondChildInput;

    [Parameter]
    public string SecondChildInput
    {
        get { return _secondChildInput; }
        set { _secondChildInput = value;
            SecondChildInputChanged.InvokeAsync(value);
        }
    }

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

真不知道问题出在哪里。 :/

我尝试通过 Action 更改 EventCallBack,但当值更改时似乎不会将更改提升到父项。

c# asp.net components blazor two-way-binding
1个回答
0
投票

您的代码导致了无限循环,因为子组件和父组件永远相互通知该值已更改。检查这个相关的GitHub问题.

您可以添加检查新值是否与先前值不同以停止无限循环:

[Parameter]
public string SecondChildInput
{
    get { return _secondChildInput; }
    set 
    { 
        if (_secondChildInput != value)
        {
            _secondChildInput = value;
            SecondChildInputChanged.InvokeAsync(value);
        }
    }
}

但是正如 Steve Sanderson 在我上面提到的问题中提到的,组件不应该设置自己的参数。所以我推荐这种方法:

FirstChildComponent.razor

<input value="@FirstChildInput" @oninput="OnInputChanged" />

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

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

    private async Task OnInputChanged(ChangeEventArgs e)
    {
        var value = e?.Value?.ToString();
        await FirstChildInputChanged.InvokeAsync(value);
    }
}

和类似的

SecondChildComponent.razor

演示

© www.soinside.com 2019 - 2024. All rights reserved.