存储对运行时创建的组件的引用
Storing references to components created at runtime
给定以下 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
事件的事件处理程序中触发。在当前情况下,EventCallback 应该 return 到父组件,其 html 标记中的子组件的 ID,比如输入 html 元素, keydown
事件发生.我希望你能成功地理解我所说的...如果没有,请不要犹豫提问。
更新:
注意:我在之前的代码示例中添加了一些代码,以演示如何在您点击每个 ChildComponent 中嵌入的输入 Html 元素的 KeyDown 按钮时 return 每个 ChildComponent 的 ID子组件。此外,我的代码还演示了如何在 KeyDown 事件发生时 return 对每个组件的引用:
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();
}
}
给定以下 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
事件的事件处理程序中触发。在当前情况下,EventCallback 应该 return 到父组件,其 html 标记中的子组件的 ID,比如输入 html 元素, keydown
事件发生.我希望你能成功地理解我所说的...如果没有,请不要犹豫提问。
更新:
注意:我在之前的代码示例中添加了一些代码,以演示如何在您点击每个 ChildComponent 中嵌入的输入 Html 元素的 KeyDown 按钮时 return 每个 ChildComponent 的 ID子组件。此外,我的代码还演示了如何在 KeyDown 事件发生时 return 对每个组件的引用:
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();
}
}