如何在开拓者中从事件回调中获取返回值?



我的情况是这样的:我正在尝试实现和自动完成。

自动完成将有一个Parameter,该将接收string并返回IEnumerable<TValue>

这是我正在尝试做的事情的一个例子

自动完成.剃刀

@code {
[Parameter]
public SOME_TYPE GetItems { get; set; }
async void Foo(){
IEnumerable<TValue> items = await GetItems(SomeString);
// do something with items
} 
}

ParentComponent.razor

<Autocomplete TValue="SomeEntity"
GetItems="@GetItems" />
@code {        
SOME_TYPE GetItems(string name) {
IEnumerable<SomeEntity> entity = await GetEntitys(name);
return entity;
} 
}

问题是我不知道该在SOME_TYPE放什么.我应该使用EventCallback吗?Action?我应该使用什么?

我尝试使用EventCallback但看起来我无法从EventCallback获得返回值?我不知道。

我只是找出如何做到这一点,我应该使用Func<string, Task<IEnumerable<TValue>>>.

[Parameter]
public Func<string, Task<IEnumerable<TValue>>> GetItems { get; set; }

public async Task<IEnumerable<Employee>> GetItems(string name) {
IEnumerable<SomeEntity> entity = await GetEntitys(name);
return entity;
} 

您也可以为此使用EventCallback参数:

public class CancelArg
{
public bool Value { get; set; }
}
[Parameter]
public EventCallback<CancelArg> OnFoo { get; set; }
async Task CallerInChild()
{
var cancel = new CancelArg();
await OnFoo.InvokeAsync(cancel);
if (cancel.Value)
{
// cancelled ...
}
}
void HandlerInParent(CancelArg cancel)
{
cancel.Value = true;
}

在子组件中:

<div class="form-group">
<label for="ddSetStatus">Status</label>
<InputSelect class="form-control" id="ddSetStatus" @bind-Value="@Status" @oninput="@((e) => ChangedSelection(e))">
<option value="1">Draft </option>
<option value="2">Published </option>
<option value="3">Archived </option>
</InputSelect>
</div>
@code
{
[Parameter] public EventCallback<int> OnStatusSelected { get; set; }
[Parameter] public int Status { get; set; }
private async Task ChangedSelection(ChangeEventArgs args)
{
await OnStatusSelected.InvokeAsync(int.Parse(args.Value.ToString()));
}
}

然后在父页面或组件中使用所选值:

创建一个组件(在本例中称为 DocStatus)并定义事件处理方法

在标记区域中:


<DocStatus Status="@Status" OnStatusSelected="StatusSelectionHandler"/>

在代码区域中:


private void StatusSelectionHandler(int newValue)
{
Status = newValue;   
}

基于@kzaw响应,我创建了一个扩展方法:

public static class EventCallbackExtensions
{
public static async Task<TOutput?> InvokeReturnAsync<TInput, TOutput>(this EventCallback<EventCallbackReturnParameter<TInput, TOutput?>> callback, TInput input, TOutput? output = default)
{
var callbackReturn = new EventCallbackReturnParameter<TInput, TOutput?>()
{
Value = input,
OutputValue = output
};
await callback.InvokeAsync(callbackReturn);
return callbackReturn.OutputValue;
}
}

它使用泛型类来存储输入和输出,例如:

public sealed class EventCallbackReturnParameter<TInput, TOutput>
{
public TInput? Value { get; set; }
public TOutput? OutputValue { get; set; }
public EventCallbackReturnParameter() 
{
}
public EventCallbackReturnParameter(TOutput outputValue) 
{
OutputValue = outputValue;
}
public EventCallbackReturnParameter(TInput value, TOutput outputValue) 
{
Value = value;
OutputValue = outputValue;
}
}

可以像这样使用:

ChildComponent.razor

<span @onclick="async ()=> await OnSelect()">Item to select</span>
@code
{
[Parameter] public EventCallback<EventCallbackReturnParameter<string, string>> OnItemSelected { get; set; }
private async Task OnSelect() 
{
var outputText = await OnItemSelected.InvokeReturnAsync("selected item");
}
}

ParentComponent.razor

<ListRow OnSelected="OnSelected" />
@code
{
private async Task OnSelected(EventCallbackReturnParameter<string, string> callbackParameter) 
{
callbackParameter.OutputValue = "Output value";
}
}

相关内容

  • 没有找到相关文章

最新更新