给定以下Blazor组件:
@foreach (var col in columns)
{
@foreach (row in rows)
{
<MyInput @onkeydown="KeyDown" @ref="NewInput"></MyInput>
}
}
@code {
private List<MyInput> inputs = new List<MyInput>();
private MyInput NewInput
{
get { return _NewInput; }
set
{
_NewInput = value;
inputs.Add(_NewInput);
}
}
MyInput _NewInput;
private async Task KeyDown(KeyboardEventArgs args)
{
if (args.Code == "ArrowDown")
{
//TODO: Find out which dynamic MyInput-instance
// within the inputs collection triggered the event
}
}
}
我正在尝试使用箭头键在MyInputs之间添加光标导航。为了实现这一点,我显然需要知道是哪个MyInput组件触发了关键事件。
我设法通过滥用@ref属性将所有MyInput实例存储到一个列表中,但我不知道列表中的哪个实例触发了该事件。
Blazor是否提供了任何方法来找出是哪个动态创建的MyInput实例触发了事件?
假设您定义了一个名为">
ChildComponent.razor
<div>@ID.ToString()</div>
@code {
[Parameter]
public int ID { get; set; }
}
它有一个参数属性ID,由父组件提供,如下所示:
ParentComponent.razor
@for (int i = 0; i < 10; i++)
{
<ChildComponent @ref="component" ID="i" />
}
@code
{
private ChildComponent component { set => components.Add(value); }
List<ChildComponent> components = new List<ChildComponent>();
protected override void OnInitialized()
{
foreach (var component in components)
{
Console.WriteLine(component.ID);
}
}
}
现在,您可以通过其ID来识别组件。这是一种简单有效的方法,尽管您可以通过其他方式来实现。
注意:这是错误的:
<MyInput @onkeydown="KeyDown" @ref="NewInput"></MyInput>
因为您指定了一个方法的名称;KeyDown";,到@onkeydown编译器指令,该指令仅适用于Html标记,不适用于组件。
你可以这样做:
<MyInput ID="id" @ref="NewInput"></MyInput>
请注意,ID应该是在MyInput组件中定义的参数属性,它是一个子组件。您还必须定义一个EventCallback,它应该由keydown
事件的事件处理程序触发。在cuurent的情况下,EventCallback应该返回到父组件,即keydown
事件发生在其html标记(例如输入html元素(中的子组件的ID。我希望你能听懂我的话。。。如果没有,请毫不犹豫地提出问题。
更新:
注意:我在前面的代码示例中添加了一些代码,以演示当您点击嵌入每个子组件中的输入Html元素的KeyDown按钮时,如何返回每个子组件的ID。此外,我的代码还演示了如何在KeyDown事件发生时返回对每个组件的引用:
ChildComponent.razor
<input type="text" @onkeydown="@KeyDown" />
@code {
[Parameter]
public int ID { get; set; }
// [Parameter]
// public EventCallback<int> CallBack { get; set; }
[Parameter]
public EventCallback<ChildComponent> CallBack { get; set; }
private void KeyDown(KeyboardEventArgs args)
{
// if (args.Code == "ArrowDown")
// {
// InvokeAsync(() => { CallBack.InvokeAsync(ID); });
// }
if (args.Code == "ArrowDown")
{
InvokeAsync(() => { CallBack.InvokeAsync(this); });
}
}
}
ParentComponent.razor
<div>@output</div>
@for (int i = 0; i < 10; i++)
{
<ChildComponent CallBack="ShowID" @ref="component" ID="i" />
}
@code
{
private ChildComponent component { set => components.Add(value); }
List<ChildComponent> components = new List<ChildComponent>();
protected override void OnInitialized()
{
foreach (var component in components)
{
Console.WriteLine(component.ID);
}
}
private string output = "";
// private void ShowID(int id)
// {
// output = id.ToString();
// }
private void ShowID(ChildComponent child)
{
output = child.ID.ToString();
}
}