c# - 根据传入参数更新传出参数
问题描述
编辑:回购在这里 - https://github.com/cedwards-telis/HowToBind
在下面的示例中,当检查“相同的帐单地址”框时更新帐单地址将更新ShiptiphAddress组件内的运输地址,但不会在父母中更新订单中的运输地址,IE不会在订单摘要后出现更新我想发生。为此,它必须再次从 Child1 到 Parent 再到 Child2 到 Parent。
我意识到这个例子根本不是最小的,但至少它是说明性的!
我不能在属性设置器中使用 Async ShippingAddressTextChanged.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());
}
}
解决方案
这是针对您的问题的上述方法的另一种方法:
定义订单服务。
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;
}
还有进一步的改进,但是如果您想朝这个方向发展,这应该可以帮助您入门。
推荐阅读
- git - git stash pop,我遇到了这个问题
- handlebars.js - Handlebars 非块表达式助手,可以使用它的参数名称字符串以及它在上下文中的值查找
- rcpp - 使用 Rcpp 构建 R 包
- sql - Postgres 9.6 到 12.7 pg_upgrade 错误 - 由于管理员命令而终止连接
- c# - WinForms 队列 GUI 网格布局
- optimization - 在哪种情况下/场景我应该使用 GPU(而不是 CPU)来运行我的程序?
- excel - 日期/时间格式的excel sql vba运行时错误80040e07
- c++ - 从派生构造函数调用受保护的构造函数
- r - 为组 dplyr 中的唯一值分配唯一编号?
- html - 如何避免浏览器将我的输入视为信用卡号码?(他们不是!)