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

Posted

技术标签:

【中文标题】为啥提交类型的按钮在父组件中触发OnInit【英文标题】:Why does button of type submit trigger OnInit in the parent component为什么提交类型的按钮在父组件中触发OnInit 【发布时间】:2019-06-20 06:14:06 【问题描述】:

有一个parent和一个child组件,child有一个带有2个按钮的表单,一个是submit类型,另一个是button类型。它们的onclick处理程序都调用@987654327 @ 让家长回复。 在父组件处理了子组件发送的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> onsubmitget;set;
     public void OnPressSubmit()
     
       this.onsubmit?.Invoke(7);
     
     [Parameter] protected Action<int> oncancelget;set;
     public void OnPressCancel()
     
       this.oncancel?.Invoke(7);
     

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

OUTPUT(用于submit类型的按钮)

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

OUTPUT(用于button类型的按钮)

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

为什么submit 按钮在父级AFTER 上也触发OnInit,父级处理事件?

【问题讨论】:

这是正确的输出顺序吗? From Handler, x=7 //in eventhandler From OnInit, x=3 From OnAfterRender, x=3 是的,首先它分配正确然后,页面刷新。parent页面在child标签关闭时进行完全刷新是否正常?根据条件@if,孩子在父母中 【参考方案1】:

试试这个: 添加一个 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。

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

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

【讨论】:

我应该声明我的Child 是一个带有两个按钮的表单:一个是submit 类型,另一个是button 类型。它们都向parent 发起事件。 button 类型之一不会在 parent 上触发 OnInit

以上是关于为啥提交类型的按钮在父组件中触发OnInit的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Jest 中的提交按钮触发 Vuetify 表单提交

在父组件中显示来自子组件的按钮的结果 - Angular

在 React 中使用父组件中的按钮提交表单

vue.js怎样解决按钮多次点击重复提交

在父组件中单击按钮时从子组件执行功能:Angular2

当从执行路径更改的表单中触发取消按钮时,组件更改会暂时暂停?