子组件:如何根据另一个组件的状态启用输入

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

我正在开发一个 Blazor WebAssembly 应用程序,其中有一个父组件

Father
,其中包含两个子组件(
Child1
Child2
)。
Child2
仅当满足 Child1 中的特定条件时才应启用,但我在维护这些组件之间的正确状态时遇到了问题。

Child1
中,我有一个自动完成组件 MudAutocomplete,选择该组件后,应通过在父组件
Child2
中设置状态
Model.SuperUser
来启用
Father
中的某些功能。我确保在更新
StateHasChanged()
中的状态后调用
Child1
,但即使满足条件
Child2
Model.SuperUser != null
中的输入仍处于禁用状态。

@page "/father"

<Child1 Model="model" />
<Child2 Model="model" />

@code {

    private MyModel model;
    protected override void OnInitialized()
    {
        model = new MyModel();
        base.OnInitialized();
    }


    public class MyModel
    {
        public int? AdminUserId { get; set; }
        public UserDTO? AdminUser { get; set; }

        public int? CustomerUserId { get; set; }
        public UserDTO? CustomerUser { get; set; }

        public int? SuperUserId { get; set; }
        public UserDTO? SuperUser { get; set; }
    }
}

// Child1.razor
<!-- SuperUser -->
<div class="form-group col-6">
    <label class="required" for="SuperUser">@Localizer["SuperUser"]</label>
    <MudAutocomplete T="UserDTO"
                     ResetValueOnEmptyText="true"
                     SearchFunc="@SearchSuperUser"
                     ToStringFunc="@(e => e == null ? null : $"{e.Email}")"
                     ShowProgressIndicator="true"
                     Variant="Variant.Outlined"
                     Clearable="true"
                     Placeholder="@Localizer["PleaseSelectSuperUser"]"
                     OnClearButtonClick="OnSuperUserCleared"
                     ProgressIndicatorColor="Color.Primary"
                     ValueChanged="OnSuperUserValueChanged">
        <NoItemsTemplate>
            <MudList Clickable="false">
                <MudListItem>
                    @Localizer["NoItemsWasFound"]
                </MudListItem>
            </MudList>
        </NoItemsTemplate>
        <BeforeItemsTemplate>
            <MudText Color="Color.Primary" Class="mud-list-item mud-list-item-gutters mud-list-item-clickable mud-ripple">@Localizer["PleaseSelectSuperUser"]</MudText>
        </BeforeItemsTemplate>
        <ProgressIndicatorInPopoverTemplate>
            <MudList Clickable="false">
                <MudListItem>
                    @Localizer["Loading"]
                </MudListItem>
            </MudList>
        </ProgressIndicatorInPopoverTemplate>
    </MudAutocomplete>
    <ValidationMessage For="@(() => Model.SuperUserId)" />
</div>

@code {
    [Parameter][EditorRequired] public MyModel Model { get; set; } = null!;

    private async Task<IEnumerable<UserDTO>> SearchSuperUser(string value)
    {
        var result = await _myService.GetSuperUserFiltered(value);
        if (result != null)
        {
            return result;
        }
        return new List<UserDTO>();

    }

    private void OnSuperUserCleared(MouseEventArgs args)
    {
        Model.SuperUser = null;
        Model.SuperUserId = null;
        StateHasChanged();
    }

    private void OnSuperUserValueChanged(UserDTO value)
    {
        Model.SuperUser = value;
        Model.SuperUserId = value.Id;
        StateHasChanged();
    }
}

// Child2.razor
<!-- AdminUser -->
<div class="form-group col-6">
    <label class="required" for="AdminUser">@Localizer["AdminUser"]</label>
    <MudAutocomplete T="UserDTO"
                     ResetValueOnEmptyText="true"
                     SearchFunc="@SearchAdminUser"
                     ToStringFunc="@(e => e == null ? null : $"{e.Email}")"
                     ShowProgressIndicator="true"
                     Variant="Variant.Outlined"
                     Clearable="true"
                     Placeholder="@Localizer["PleaseSelectAdminUser"]"
                     OnClearButtonClick="OnAdminUserCleared"
                     ProgressIndicatorColor="Color.Primary"
                     ValueChanged="OnAdminUserValueChanged"
                     Disabled="Model.SuperUser == null"> <!-- It should be enabled only id SuperUser is selected -->
        <NoItemsTemplate>
            <MudList Clickable="false">
                <MudListItem>
                    @Localizer["NoItemsWasFound"]
                </MudListItem>
            </MudList>
        </NoItemsTemplate>
        <BeforeItemsTemplate>
            <MudText Color="Color.Primary" Class="mud-list-item mud-list-item-gutters mud-list-item-clickable mud-ripple">@Localizer["PleaseSelectAdminUser"]</MudText>
        </BeforeItemsTemplate>
        <ProgressIndicatorInPopoverTemplate>
            <MudList Clickable="false">
                <MudListItem>
                    @Localizer["Loading"]
                </MudListItem>
            </MudList>
        </ProgressIndicatorInPopoverTemplate>
    </MudAutocomplete>
    <ValidationMessage For="@(() => Model.AdminUserId)" />
</div>

@code {
    [Parameter][EditorRequired] public MyModel Model { get; set; } = null!;

    private async Task<IEnumerable<UserDTO>> SearchAdminUser(string value)
    {
        if (Model.SuperUserId.HasValue && Model.SuperUserId.Value > 0)
        {
            var filter = new { Model.SuperUserId, value };
            var result = await _myService.GetAdminUserBySuperUserFiltered(filter);
            if (result != null)
            {
                return result;
            }
        }
        return new List<UserDTO>();

    }

    private void OnAdminUserCleared(MouseEventArgs args)
    {
        Model.AdminUser = null;
        Model.AdminUserId = null;
        StateHasChanged();
    }

    private void OnAdminUserValueChanged(UserDTO value)
    {
        Model.AdminUser = value;
        Model.AdminUserId = value.Id;
        StateHasChanged();
    }
}

尽管在

Model.SuperUser
中正确更新
Child1
并调用
StateHasChanged()
,但
Disabled="Model.SuperUser == null"
中的
Child2
条件并未按预期启用输入。

关于如何根据

Child2
Model.SuperUser
的状态正确启用/禁用
Child1
中的输入有什么建议吗?

c# blazor blazor-webassembly mudblazor
1个回答
0
投票

您可以使用 级联值

Model
Parent
传递到
Childred
元素。然后使用
Children
中的事件回调将更改传递回
Parent

这里是您提供的代码的修改版本。

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