簡體   English   中英

無法在 BuildRenderTree Blazor WASM 中使用構建 function

[英]Cannot use build function inside BuildRenderTree Blazor WASM

我想動態構建 Blazor 組件,但我在 WASM 上遇到一個奇怪的錯誤,而服務器端中的相同代碼可以工作。

很抱歉,但我不知道如何詳細解釋錯誤或錯誤,但基本上如果我在覆蓋的 RenderBuildTree 上構建組件,它可以正常工作,但如果我在 RenderBuildTree 中調用另一個 BuildFunction,我會得到一個System.InvalidOperationException: The render handle is not yet assigned. 錯誤。

要重現錯誤,請嘗試在 TextField 中輸入一些內容並單擊它以觸發 ValueChanged。

最小可重現代碼: https://try.mudblazor.com/snippet/ckQmYGOeIEycwaoV

你在錯誤的實例上調用它。
核心問題是TestBaseComponent TestBaseComponent = new();

public class TestComponentBuilder : ComponentBase
{
    // private static readonly TestBaseComponent TestBaseComponent = new();
    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        // TestBaseComponent.Build(builder);
        builder.OpenComponent(1, typeof(TestBaseComponent));
        builder.CloseComponent();
    }
}

您的TestComponentBuilder組件應該從TestBaseComponent組件派生,而不是在TestComponentBuilder組件中實例化TestBaseComponent 這就是你如何做 OOP。 Additionally, though TestBaseComponent component is a C# class, it should not be instantiated like a normal C# object, as Blazor needs to instantiate it in a special way in order to render it propperly.

以下是對您的有效代碼的更新。

TestBaseComponent.cs

public class TestBaseComponent : ComponentBase
    {
        [Parameter]
    public string Value { get; set; }
    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        Build(builder);
    }

    public void Build(RenderTreeBuilder builder)
    {
        var index = 1;
        builder.OpenComponent(index++, typeof(MudTextField<string>));
        try
        {
            builder.AddAttribute(index++, "LabelName", "Label!!");
            builder.AddAttribute(index++, "Value", Value);
            builder.AddAttribute(index++, "ValueChanged", EventCallback.Factory.Create(this, (string newValue) =>
            {
                try
                {
                    Console.WriteLine("ValueChanged: " + newValue);
                    Value = newValue;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }));
        }
        finally
        {
            builder.CloseComponent();
        }
    }
    } 

TestComponentBuilder.cs

public class TestComponentBuilder : TestBaseComponent
    {
        //private static readonly TestBaseComponent TestBaseComponent = new();
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            base.Build(builder);
        }
    }

__Main.razor

<MudText>This works!</MudText>
<TestBaseComponent Value="Hello"></TestBaseComponent>
<MudText>This doesnt work</MudText>
<TestComponentBuilder Value="World"></TestComponentBuilder>

注意:您應該對序列號進行硬編碼,而不是使用index++. 讀這個

好的,這就是你想要的。 它有效,但我會像上一個答案一樣這樣做:

public class TestComponentBuilder : ComponentBase
    {
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            builder.OpenComponent(0, typeof(TestBaseComponent));

            builder.AddAttribute(1, "Value", "Hello, Blazor");
            builder.CloseComponent();
         
        }
      
    }

您還可以改進上述內容,如下所示:

public class TestComponentBuilder : ComponentBase
    {
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            builder.OpenComponent(0, typeof(TestBaseComponent));

            builder.AddAttribute(1, "Value", Value);
            builder.CloseComponent();
         
        }

        [Parameter]
        public string Value { get; set; } 
    }

__Main.razor

<MudText>This works!</MudText>
<TestBaseComponent Value="Hello"></TestBaseComponent>
<MudText>This doesnt work</MudText>

<TestComponentBuilder Value="Hello, Blazor"></TestComponentBuilder>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM