如何有条件地防止Blazor中输入组件内部的默认值?

如何有条件地防止Blazor中输入组件内部的默认值?,blazor,blazor-server-side,Blazor,Blazor Server Side,我希望仅在按下enter键时才防止输入的默认行为(htmlinput标记为type=“text”) protected void HandleKeyPress(KeyboardEventArgs keyboardEventArgs) { if (keyboardEventArgs.Key == "Enter") { // prevent default } // rest of function } 我知道我可以做这样的事情,但如

我希望仅在按下enter键时才防止输入的默认行为(html
input
标记为
type=“text”

protected void HandleKeyPress(KeyboardEventArgs keyboardEventArgs)
{
    if (keyboardEventArgs.Key == "Enter")
    {
        // prevent default
    }     

    // rest of function  
}
我知道我可以做这样的事情,但如何在事件处理程序中有条件地做到这一点

在javascript中,我可以执行以下操作

function(e){
    if(e.keyCode == 13) {
      e.preventDefault();
    }
    // rest of function
}
在blazor中如何做同样的事情

编辑: 我正在为库进行输入,但我无法更改submit按钮,我需要在我的输入组件中阻止此操作。

简而言之,您不能(在C#中)

这是因为所有JavaScript互操作都是异步完成的,并且事件的条件取消必须始终是同步的

当您的输入控件处于焦点时,您希望阻止库用户按enter键提交表单,这似乎有些奇怪

但是,您可以编写一些javascript来为您完成这项工作。您可以在html输入控件中使用
@ref=SomeVariable
,当
firstRender==true


你可以在这里阅读如何做这类事情

感谢enet和Peter Morris的帮助

经过多次尝试,看起来唯一的方法就是使用javascript

.js

.剃刀

<input @ref="InputRef" />

@code {
    [Inject]
    private IJSRuntime JSRuntime { get; set; }

    public ElementReference InputRef { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        if (PreventDefaultOnEnter)
        {
            await JSRuntime.InvokeVoidAsync("preventDefaultOnEnter", InputRef);
        }
    }

    public override async void Dispose()
    {
        base.Dispose();
        if (PreventDefaultOnEnter)
        {
            await JSRuntime.InvokeVoidAsync("preventDefaultOnEnter", InputRef, true);
        }
    }
}

@代码{
[注入]
私有IJSRuntime运行时{get;set;}
公共元素引用InputRef{get;set;}
受保护的重写异步任务OnInitializedAsync()
{
wait base.OnInitializedAsync();
如果(防止默认值)
{
等待JSRuntime.InvokeVoidAsync(“PreventDefaultOnter”,InputRef);
}
}
公共重写异步void Dispose()
{
base.Dispose();
如果(防止默认值)
{
等待JSRuntime.InvokeVoidAsync(“PreventDefaultOnNet”,InputRef,true);
}
}
}

如前所述,您必须在JavaScript中执行此操作。如果执行此JavaScript代码:

window.addEventListener("load", function () {
    //This will be called when a key is pressed
    var preventDefaultOnEnterCallback = function (e) {
        if (e.keyCode === 13 || e.key === "Enter") {
            // console.log("Prevented default.")
            e.preventDefault();
            return false;
        }
    };
    //This will add key event listener on all nodes with the class preventEnter.
    function setupPreventDefaultOnEnterOnNode(node, add) {
        if (node instanceof HTMLElement) {
            var el = node;
            //Check if main element contains class
            if (el.classList.contains("prevent-default-on-enter") && add) {
                // console.log("Adding preventer: " + el.id);
                el.addEventListener('keydown', preventDefaultOnEnterCallback, false);
            }
            else {
                // console.log("Removing preventer: " + el.id);
                el.removeEventListener('keydown', preventDefaultOnEnterCallback, false);
            }
        }
    }
    //This will add key event listener on all nodes with the class preventEnter.
    function setupPreventDefaultOnEnterOnElements(nodelist, add) {
        for (var i = 0; i < nodelist.length; i++) {
            var node = nodelist[i];
            if (node instanceof HTMLElement) {
                var el = node;
                //Check if main element contains class
                setupPreventDefaultOnEnterOnNode(node, add);
                //Check if any child nodes contains class
                var elements = el.getElementsByClassName("prevent-default-on-enter");
                for (var i_1 = 0; i_1 < elements.length; i_1++) {
                    setupPreventDefaultOnEnterOnNode(elements[i_1], add);
                }
            }
        }
    }
    // Create an observer instance linked to the callback function
    // Read more: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
    var preventDefaultOnEnterObserver = new MutationObserver(function (mutations) {
        for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
            var mutation = mutations_1[_i];
            if (mutation.type === 'childList') {
                // A child node has been added or removed.
                setupPreventDefaultOnEnterOnElements(mutation.addedNodes, true);
            }
            else if (mutation.type === 'attributes') {
                if (mutation.attributeName === "class") {
                    console.log('The ' + mutation.attributeName + ' attribute was modified on' + mutation.target.id);
                    //class was modified on this node. Remove previous event handler (if any).
                    setupPreventDefaultOnEnterOnNode(mutation.target, false);
                    //And add event handler if class i specified.
                    setupPreventDefaultOnEnterOnNode(mutation.target, true);
                }
            }
        }
    });
    // Only observe changes in nodes in the whole tree, but do not observe attributes.
    var preventDefaultOnEnterObserverConfig = { subtree: true, childList: true, attributes: true };
    // Start observing the target node for configured mutations
    preventDefaultOnEnterObserver.observe(document, preventDefaultOnEnterObserverConfig);
    //Also check all elements when loaded.
    setupPreventDefaultOnEnterOnElements(document.getElementsByClassName("prevent-default-on-enter"), true);
});

你可以随时做这件事。无需在razor代码中与JavaScript交互:-)

我在这个场景中采用的解决方案是:

  • 创建了一个
    javascript
    函数,用于处理
    input
    元素中发生的事件
  • 在C#中创建方法,根据满足的
    JS
    条件调用这些方法
  • 2.1。如果触发了
    keyup
    事件,我们希望在C中设置对象属性的最终值#

    2.2。另一方面,如果触发了
    keydown
    ,并且该键是我们特别感兴趣的键之一(enter/up/down/etc…),那么我们希望触发一些特定的逻辑

    下面是函数的外观:

    <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>
    

    我觉得我不应该从另一个线程粘贴我自己的答案,所以只需在这里用完整的代码示例检查剩余的答案:

    要实现您需要的功能,您需要像这样设置组件的html

    
    @事件文本

    您可以将preventDefault设置为变量,然后在C#代码中更改它

    @code{
    私人住宅应予以保护;
    私有字符串eventText=“”;
    私有void KeyDown(KeyboardEventArgs e){
    如果(例如,代码为“输入”){
    eventText=“按Enter键”;
    shouldPrevent=true;
    返回;
    }
    eventText=“”;
    shouldPrevent=false;
    }
    }
    

    您可以在这里检查工作代码。

    什么类型的输入?您的意思是如果(keyboardEventArgs.Key==“Enter”)而不是如果(keyboardEventArgs.Key!=“Enter”),对吗?@enet抱歉,我的输入错误。我刚刚又修正了一个问题,什么类型的输入?文本,按钮………@enet html
    输入
    标记列表很长。。。什么类型的输入?
    当您的输入控件处于焦点时,您可能希望阻止您的库用户按enter键提交表单,这似乎有些奇怪
    我正在进行自动完成输入,要在自动完成下拉列表中选择一项,用户必须按enter键。如果我不阻止默认设置,它将选择项目,但也会提交表单。@Peter Morris,为什么他不能。我给他发了一个代码,这个代码运行得非常好,但需要做很多工作。所以现在我给了他一个最简单的解决方案:嵌入C#的JavaScript。@enet我认为他的意思是,
    你不能有条件地防止默认值,只有blazor
    JS代码似乎泄漏了。它将函数对象的实例传递给removeEventListener,该实例与传递给addEventListener的实例不同。
    <input type="text" class="prevent-default-on-enter" />
    
    <button type="submit" class="prevent-default-on-enter">Submit</button>
    
    <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>
    
    [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();
    }