【问题标题】:How to update Blazor UI in same callback before calling a ref function?如何在调用 ref 函数之前在同一回调中更新 Blazor UI?
【发布时间】:2020-12-04 18:45:22
【问题描述】:

在我的组件中,我有一个子组件 (FooComponent),我将参数传递给它并获得一个 ref。

Parent.razor

<FooComponent @ref="FooComponentRef" FooParameter="@MyValue"/>
    
<button @onclick="Test">@MyValue</button>
    
@code {
    FooComponent FooComponentRef { get; set; }
    
    string MyValue { get; set; }
    
    int count { get; set; }
    
    void Test(){
        MyValue = "SomeValue" + count++;            
        FooComponentRef.FooFunction();
    }
}

我修改了代码,使其成为一个简单且可测试的示例

我有一个函数 (Test) 将更新在参数中传递的属性 (MyValue 传递给 FooParameter) 并从 ref 调用一个函数 (FooFunctionFooComponent) .

FooComponent里面

FooComponent.razor

<div>
    <div>FooParameter: @FooParameter</div>
    <div>ValueUsedInFooFunction: @ValueUsedInFooFunction</div>
</div>

@code {
    [Parameter]
    public string FooParameter { get; set; }

    public string ValueUsedInFooFunction { get; set; }

    public void FooFunction()
    {
        // This function is using FooParameter to make some logic
        ValueUsedInFooFunction = FooParameter;
    }
}

我修改了代码,使其成为一个简单且可测试的示例

它使用FooFunction中的FooParameter来做一些逻辑。

问题是当我更改MyValue并调用FooFunction时,组件还没有更新,所以它使用FooParameter的“旧”值,但我需要使用新设置的值,这是正确的MyValue

让这个问题难以解决的另一件事是我无法更改 FooFunction(这不是我创建的函数)。

我已经尝试过使用所有方法(StateHasChangedInvokeAsync),但仍然没有解决方案。

我需要的是我的Test 函数来做类似的事情

void Test(){
    MyValue = "SomeValue" + count++;   
    
    // Somehow update UI so FooParameter have the correct value of MyValue          
    
    FooComponentRef.FooFunction();    
}

这里是blazor fiddle to test

在小提琴中,当点击按钮并调用Test函数时,你会看到ValueUsedInFooFunction始终是FooParameter的“旧”值,这意味着FooFunctionFooParameter 正在更新中。

【问题讨论】:

标签: blazor blazor-server-side


【解决方案1】:

此更改将使此工作:

 void Test(){
    MyValue = "SomeValue" + count++;    
    FooComponentRef.FooParameter = MyValue;
    FooComponentRef.FooFunction();
}

【讨论】:

  • 您可能不希望以这种方式设置组件的属性,因为它会绕过 blazors 方法(例如 OnParametersSet)。事实上,它甚至会生成一个分析器警告BL0005(组件参数不应设置在其声明的组件之外。这样做可能会导致运行时出现意外行为。)
  • 谢谢,我没有意识到我的错误。
【解决方案2】:

您将传递一个对象,即 Dto,而不是传递字符串参数 (MyValue),该对象具有一个包含该值的字符串属性。这是 Dto:

   public class FooDto
{
    public string MyValue { get; set; }
}

这是索引:

  @page "/"
@using WebApplication2.Models

<FooComponent @ref="FooComponentRef" FooDtoParameter="@_dto" />

<button @onclick="Test">@MyValue</button>

@code {
    FooComponent FooComponentRef { get; set; }

    string MyValue { get; set; }

    int count { get; set; }

    /// <inheritdoc />
    protected override void OnInitialized()
    {
        base.OnInitialized();
        
    // The Dto class will be passed as a parameter to foo.
    _dto = new FooDto();
    }

    void Test()
    {
        _dto.MyValue = "SomeValue" + count++;

        FooComponentRef.FooFunction();
    }

    
    private FooDto _dto;
}

富:

@using WebApplication2.Models
<div>
    <div>FooParameter: @FooDtoParameter.MyValue</div>
    <div>ValueUsedInFooFunction: @ValueUsedInFooFunction</div>
</div>

@code {
    [Parameter]
    public FooDto FooDtoParameter { get; set; }

    public string ValueUsedInFooFunction { get; set; }

    public void FooFunction()
    {
    // This function is using FooParameter to make some logic
        ValueUsedInFooFunction = FooDtoParameter.MyValue;
    }
}

子组件和父组件使用相同的 Dto 对象进行通信,当您更改属性的值时,子组件可以立即访问该信息。

我知道可能有更好的方法来做到这一点,但我正在尝试回答这个具体案例的问题。

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 2023-03-22
    • 2020-08-07
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    相关资源
    最近更新 更多