为什么提交类型的按钮在父组件中触发OnInit

时间:2019-01-26 19:00:38

标签: c# forms components eventemitter blazor

具有parentchild组件,child的表单带有2个按钮,其中一个按钮类型为submit,另一个按钮类型为button它们的onclick处理函数都调用Actions以便父级做出响应。 在处理从子级发送的event后的父级组件中,由submit按钮触发的事件也会触发父级上的OnInit。 为什么会这样?

示例:

父母

<Child onsubmit=@((value)=>OnSubmit(value)) 
       oncancel=@((value)=>OnCancel(value))></Child>
@functions()
{ 
  private int x=3;
  protected override void OnInit()
  {
    Console.WriteLine($"From OnInit ,x={this.x}");
  }
  protected override void OnAfterRender()
  {
    Console.WriteLine($"From AfterRender,x={this.x}");
  }
  protected void OnSubmit(int _x) 
  { 
     //lets say child sends x=7
     this.x=_x;
     Console.WriteLine($"From handler, x={this.x}");
  }
  protected void OnCancel(int _x) 
  { 
     //lets say child sends x=7
     this.x=_x;
     Console.WriteLine($"From handler, x={this.x}");
  }
}

孩子

   <form>
    <button type="submit" onclick="@(()=>OnPressSubmit())">Trigger submit</button>
     <button type="button" onclick="@(()=>OnPressCancel())">Trigger cancel</button> 
    <form>
    @functions()
    {
     [Parameter] protected Action<int> onsubmit{get;set;}
     public void OnPressSubmit()
     {
       this.onsubmit?.Invoke(7);
     }
     [Parameter] protected Action<int> oncancel{get;set;}
     public void OnPressCancel()
     {
       this.oncancel?.Invoke(7);
     }

运行此代码时,在控制台中,我将看到确实在事件处理程序variable中设置了OnEvent,但是随后在OnInit中对其进行了重置。

输出(用于类型submit的按钮)

From Handler,  x=7  //in parent eventhandler
From OnInit, x=3
From OnAfterRender, x=3

输出(用于类型button的按钮)

From Handler,  x=7  //in parent eventhandler
From OnAfterRender, x=7

为什么submit按钮也会在父级之后处理事件的OnInit上触发触发器?

1 个答案:

答案 0 :(得分:3)

尝试一下: 添加一个StateHasChanged();这样的方法:

protected void OnEvent(int _x) 
  { 
     //lets say child sends x=7
     this.x=_x;
     // If this works, then it is a bug with Blazor...
     // If not, be patient...
     StateHasChanged();

     Console.WriteLine($"From handler, x={this.x}");
  }

如果页面刷新,则输出是正确的:每当您重新加载页面时,就好像您是第一次运行它一样。现在,您应该找出页面刷新的原因。显示您的代码...

另一个问题:Blazor中的重新渲染发生于状态因事件而改变的组件(StateHasChanged()由Blazor隐式调用),或者当您显式调用StateHasChanged()方法时。仅通过受状态更改影响的组件来完成重新渲染,因此子组件可以重新渲染,而其父组件则不会。

编辑:根据您在下面所说的内容,我们现在知道为什么要重新加载页面,       因此,每次单击提交按钮时,x的值为3。       当然,当您单击另一个按钮时,不会重新渲染父组件,但是正如我上面已经演示的,如果您在OnEvent方法中添加对StateHasChanged()的调用,父组件将重新呈现。呈现,并且x变量将包含7。

注意:您不应使用type属性设置为“ submit”的按钮。 Blazor是SPA框架。您不能通过提交表单(method =“ post”)或将按钮的type属性设置为“ submit”来发布表单数据。您应该改用Ajax(HttpClient)。据我所知,Blazor阻止了表单的提交:也许只有带有method =“ post”和提交按钮的表单。

希望这会有所帮助... 如果有帮助,请标记我的回答为接受