我的解决方案如下。
在 JS 中创建以下方法。它会捕捉到 UP 和 DOWN 键击。
<script>
function subscribeToChange(componentRef, inputRef) {
console.log("subscribeToChange!");
inputRef.onkeydown = function (event) {
if (event.keyCode == "38") {
event.preventDefault();
console.log("Up key pressed");
componentRef.invokeMethodAsync('invokeFromJS');
}
else if (event.keyCode == "40") {
event.preventDefault();
console.log("Down key pressed");
componentRef.invokeMethodAsync('invokeFromJS');
}
};
inputRef.onkeyup = function (event) {
componentRef.invokeMethodAsync('setValueFromJS', inputRef.value);
};
}
</script>
剃须刀:
<input @ref="Typing3" />
@HelloFromJSStr
在 razor.cs 中:
public ElementReference Typing3;
public string HelloFromJSStr = "";
[JSInvokable("invokeFromJS")]
public async Task HelloFromJS()
{
//HelloFromJSStr += "A";
//StateHasChanged();
// do something here on UP or DOWN button presses..
}
[JSInvokable("setValueFromJS")]
public async Task SetValueFromJS(string newValue)
{
HelloFromJSStr = newValue;
StateHasChanged();
}
在我的示例中,您有 2 种方法。被触发的onkeyup 可用于将 final 值设置为属性 (HelloFromJSStr )。如果任何其他 UI 元素需要重新渲染,然后调用 StateHasChanged() 方法,如示例所示。休息是你的想象。
剩下的代码部分是初始化:
public partial class EventsAndRendering
{
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
Console.WriteLine($"{this.GetType().Name}: OnAfterRenderAsync. firstRender: {firstRender}");
if (firstRender)
{
var componentRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeAsync<object>("subscribeToChange", new object[] { componentRef, Typing3 });
}
}
// HelloFromJS()
// SetValueFromJS(string newValue)
}
DotNetObjectReference 允许我们从 JS 调用 C# 代码,而无需创建方法 statics。
所以最后的流程如下:
- 第一次呈现页面后 -> 我们创建对主要组件的引用以及对 inpout 元素的引用。
- 然后我们使用上述引用来调用
subscribeToChange JS 方法,该方法订阅我们输入元素上发生的事件。
- 在发生 keydown 事件时,我们会在 C# 中触发方法
HelloFromJS。
- 在 keyup 事件时,我们触发 C# 中的方法
SetValueFromJS。
以上只是一个例子,必须根据需要进行调整:)
灵感:https://docs.microsoft.com/en-us/aspnet/core/blazor/call-dotnet-from-javascript?view=aspnetcore-5.0#instance-method-call
编辑:考虑实现IDisposable接口来处理.Net对象:
public void Dispose()
{
componentRef?.Dispose();
}