存储对运行时创建的组件的引用



给定以下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(); 
}
}

相关内容

  • 没有找到相关文章

最新更新