首页 > 解决方案 > 根据传入参数更新传出参数

问题描述

编辑:回购在这里 - https://github.com/cedwards-telis/HowToBind

在下面的示例中,当检查“相同的帐单地址”框时更新帐单地址将更新ShiptiphAddress组件的运输地址,但不会在父母中更新订单中的运输地址,IE不会在订单摘要后出现更新我想发生。为此,它必须再次从 Child1 到 Parent 再到 Child2 到 Parent。

我意识到这个例子根本不是最小的,但至少它是说明性的!

我不能在属性设置器中使用 Async Sh​​ippingAddressTextChanged.InvokeAsync 并且可能无论如何都不应该使用。我考虑过使用 OnParametersSetAsync,但我认为我可能遗漏了一些更基本的东西。

@page "/"

<h1>Order</h1>

<BillingAddress @bind-BillingAddressText=@BillingAddressText />
<ShippingAddress @bind-ShippingAddressText=@ShippingAddressText BillingAddressText=@BillingAddressText />

<h1>Order Summary</h1>

<p>Billing Addreess is:-</p>
<address>@BillingAddressText</address>
<p>Shipping Addreess is:-</p>
<address>@ShippingAddressText</address>

@code {
    private string BillingAddressText;
    private string ShippingAddressText;
}

帐单地址.razor

<h3>Billing Address</h3>

<textarea @bind="@BillingAddressText" @bind:event="oninput" @onchange="(args)=>Update(args)" />
<address>@BillingAddressText</address>

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

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

    private async Task Update(ChangeEventArgs args)
    {
        await BillingAddressTextChanged.InvokeAsync(args.Value.ToString());
    }
}

ShippingAddress.razor

<h3>Shipping Address</h3>

<input type="checkbox" value="@sameAsBillingAddress" @onchange="SameAsBillingAddressChanged" /> Same as Billing Address
<br />
<textarea @bind="@ShippingAddressText" @bind:event="oninput" @onchange="(args)=>Update(args)" disabled="@sameAsBillingAddress" />
<address>@ShippingAddressText</address>

@code {

string shippingAddressText;
[Parameter]
public string ShippingAddressText
{
    get
    {
        return shippingAddressText;
    }
    set
    {
        shippingAddressText = value;
        if (sameAsBillingAddress)
        {
            shippingAddressText = billingAddressText;
        }
    }
}

string billingAddressText;
[Parameter]
public string BillingAddressText
{
    get
    {
        return billingAddressText;
    }
    set
    {
        billingAddressText = value;
        if (sameAsBillingAddress)
        {
            shippingAddressText = billingAddressText;
            // Line Below won't work but will hopefully help you divine my intent
            // await ShippingAddressTextChanged.InvokeAsync(billingAddressText);
        }
    }
}

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

bool sameAsBillingAddress;
private async Task SameAsBillingAddressChanged(ChangeEventArgs args)
{
    sameAsBillingAddress = (bool)args.Value;
    if (sameAsBillingAddress)
    {
        await ShippingAddressTextChanged.InvokeAsync(billingAddressText);
    }
}

private async Task Update(ChangeEventArgs args)
{
    await ShippingAddressTextChanged.InvokeAsync(args.Value.ToString());
}

}

标签: c#blazor

解决方案


这是针对您的问题的上述方法的另一种方法:

定义订单服务。

using System;

namespace Blazor.Starter.Services
{
    public class OrderService
    {

        public string ShippingAddress 
        {
            get => _ShippingAddress;
            set
            {
                if (!_ShippingAddress.Equals(value))
                {
                    NotifyOrderChanged();
                    _ShippingAddress = value;
                }
            }
        }
        private string _ShippingAddress = string.Empty;


        public string BillingAddress
        {
            get => _BillingAddress;
            set
            {
                if (!_BillingAddress.Equals(value))
                {
                    NotifyOrderChanged();
                    _BillingAddress = value;
                }
            }
        }
        private string _BillingAddress = string.Empty;

        public event EventHandler OrderChanged;

        public void NotifyOrderChanged()
            => OrderChanged.Invoke(this, EventArgs.Empty);
    }
}

在启动/程序中注册

        public void ConfigureServices(IServiceCollection services)
        {
            ...
            services.AddScoped<OrderService>();
        }

帐单地址.razor

<h3>Billing Address</h3>

<textarea @bind="@OrderService.BillingAddress" />
<address>@OrderService.BillingAddress</address>

@code {
    [Inject] OrderService OrderService { get; set; }
}

ShippingAddress.razor

Shipping Address</h3>

<input type="checkbox" @bind-value="@sameAsBillingAddress" /> Same as Billing Address
<br />
<textarea @bind="@OrderService.ShippingAddress" disabled="@sameAsBillingAddress" />
<address>@OrderService.ShippingAddress</address>

@code {

    [Inject] OrderService OrderService { get; set; }


    private bool sameAsBillingAddress
    {
        get => _sameAsBillingAddress;
        set
        {
            if (value != _sameAsBillingAddress)
            {
                if (value)
                    OrderService.ShippingAddress = OrderService.BillingAddress;
                StateHasChanged();
                _sameAsBillingAddress = value;
            }
        }
    }

    private bool _sameAsBillingAddress;
}

订购剃须刀

@page "/order"
@implements IDisposable

<h1>Order</h1>

<BillingAddress/>
<ShippingAddress/>

<h1>Order Summary</h1>

<p>Billing Addreess is:-</p>
<address>@OrderService.BillingAddress</address>
<p>Shipping Addreess is:-</p>
<address>@OrderService.ShippingAddress</address>

@code {

    [Inject] OrderService OrderService { get; set; }

    protected override Task OnInitializedAsync()
    {
        this.OrderService.OrderChanged += this.OnOrderChanged;
        return base.OnInitializedAsync();
    }

    private void OnOrderChanged(object sender, EventArgs e)
        => InvokeAsync(StateHasChanged);

    public void Dispose()
        => this.OrderService.OrderChanged -= this.OnOrderChanged;
}

还有进一步的改进,但是如果您想朝这个方向发展,这应该可以帮助您入门。


推荐阅读