【问题标题】:Executing method on Parameter change参数变更的执行方法
【发布时间】:2019-01-24 11:17:57
【问题描述】:

给定一个子组件和一个父组件,当parameter 发生更改(来自父组件)时,我试图在child 中执行一个方法。

家长

<Child value=@IsChanged></Child>

<button onclick="Update"></button>

@functions(){
  public bool IsChanged{get;set;}
  public void Update()
  {
   this.IsChanged!=this.IsChanged;
  }

儿童

@(value?"True":"False")
@functions()
{
  [Parameter]
  protected bool value {get;set;}
  
  public void SideEffect()
  {
    Console.WriteLine("has changed"); //i want this method executed when value changes from parent
  }

如您所见,我需要在参数的Child onchange 中执行方法。参数在父项中更改。

P.S
我查看了 onchange 事件处理程序,但我需要在 [Parameter] 上执行。

【问题讨论】:

    标签: c# onchange blazor


    【解决方案1】:

    您应该覆盖OnParametersSetOnParametersSetAsync 生命周期方法。

    儿童

    @(_value ? "True" : "False")
    
    @code()
    {
      private bool _value;
    
      [Parameter] public bool Value { get; set; }
    
      protected override void OnInitialized()
      {
          _value = Value;
      }
    
      protected override void OnParametersSet()
      {
          if (_value != Value)
          {
              _value = Value;
              Console.WriteLine("a parameter has changed");
          }
      }
    }
    

    【讨论】:

    • 但是如果我想为不同的参数产生不同的副作用怎么办?是否在任何参数更改时调用此方法?我不能进行模式匹配吗?
    • 当任何参数改变时都会调用该方法。因此,您可以检查每个参数并根据已更改的参数进行更改。
    • @ChrisSainty 愚蠢但显而易见的问题:您如何检查它们以确定哪个已更改?您是否必须保留所有参数的副本以便进行比较?
    • @BrianMacKay 这真的取决于你需要做什么。如果您查看 Blazor 源代码,这种模式很常见。它们保留参数的本地副本,然后在 OnParametersSet 生命周期中检查它们是否有更改。他们这样做是出于性能原因,因此只复制对性能有影响的参数。
    • @ChrisSainty 所以如果我有例如一个包含带有 50 个字符串/文本字段的 EditForm 的组件,我想确保所有这些字符串的格式正确,即所有字符串都应该被修剪,一些包含电话号码,其他包含日期等,并且 50 个字段之一被更改在父组件中,我必须保留 50 个额外的局部变量并在 OnParametersSet 中比较它们,看看是否有差异,以便我可以应用格式?肯定有更好的方法吗?这就是为什么我怀疑 Blazor 是否会在高级 LOB 应用程序中起飞。在某些方面它仍然感觉很业余。
    【解决方案2】:

    这是解决您问题的最佳和更简单的解决方案

    Child.razor

        @( _Value ? "True" : "False")
    
    
    <div>@message</div>
    
    @code
    {
        [Parameter]
        public bool Value { get;set; }
      // [Parameter]
      //  public EventCallback<bool> ValueChanged { get;set; }
    
        private bool _value;
        private bool _Value
        {
            get => _value;
            set 
            {
                if ( _value != value)
                {
                    _value = value;
                    SideEffect();
                  //  ValueChanged.InvokeAsync(_value);        
                }
            }
        }
    
        private string message;
    
        public void SideEffect()
        {
           message = $"Parameter has changed: {_Value}"; //i want this method executed when value changes from parent
         
        }
    
        protected override void OnParametersSet()
        {
                if (_Value != Value)
                {
                    _Value = Value;
                }
        }
     }
    

    用法

    @page "/"
    
    <Child Value="IsChanged" />
    
    <button type="button" @onclick="Update">Update</button>
    
    <div>IsChanged: @IsChanged</div>
    
    @code
    {
       private bool IsChanged { get; set; } = true;
    
       public void Update()
       {
          IsChanged = !IsChanged;
       }
    }
    

    【讨论】:

    • 你不应该在组件参数设置器中有任何逻辑。请参阅“组件参数应声明为自动属性,这意味着它们不应在其 get 或 set 访问器中包含自定义逻辑......不要将自定义逻辑放在 get 或 set 访问器中,因为组件参数纯粹是为了使用作为父组件将信息流向子组件的通道。”来自docs.microsoft.com/en-us/aspnet/core/blazor/components/…
    • @Christopher Edwards,对不起,但这个答案是在创建链接文档之前 2.3 年提供的,甚至在史蒂夫桑德森写道组件参数属性应该仅定义为自动属性之前,甚至在所有之前文档中的代码示例已被更改以反映这一点。但是,唉,我的代码完全按照现在应该的方式形成。请检查代码以查看我不会改变或更改参数属性值的值。我确实定义了一个名为 _Value 的本地属性,其初始值取自中的 Value 参数属性
    • OnParametersSet 方法,因此我可以随心所欲地操纵复制的值。这就是您现在应该如何编码。顺便说一句,问题不在于 get 或 set 访问器中的逻辑。不要告诉别人不要把逻辑放在那里。我经常使用组件参数属性来做到这一点。告诉他们不要更改或改变参数属性的值,并且只要不更改参数值就可以,有时必须在任一访问器中放置逻辑。希望这会有所帮助...
    • 很烦人,官方建议不要这样做,因为它很方便,而 OnParametersSet 又很不方便。也许如果你不同意这个建议,比我有更多的专业知识,你可以在文档页面上打开一个 github 问题。 Blazor 团队似乎对在 set 访问器中使用逻辑的人持怀疑态度,以防他们意外导致问题。在我看来,它应该更具确定性,更容易陷入成功的深渊。
    • 我刚刚使用与您在上面记录的相同技术编写了很多代码,但我想要一个官方认可的解决方案。我猜大多数人都在使用第三方状态管理解决方案。
    猜你喜欢
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多