Как повторно визуализировать компонент Blazor с помощью рендеринга или повторно привязать ресурс для Детей, которые визуализируют с помощью рендеринга

#asp.net-core #blazor

Вопрос:

Вопрос : Я ищу, как позволить «RenderFragment» повторно визуализировать или повторно привязывать ресурс .

Среда: Предварительный просмотр VS2019 , предварительный просмотр .net core 6 (я думаю, что это не отличается от 5)

Что Я Должен Был Попробовать :

На странице моего компонента Razor есть выделение и кнопка , выделение получит ресурс по умолчанию при первом отображении страницы , нажатие кнопки Cvent должно изменить ресурс выделения .

Это то, что я предпочитаю для правильного результата

Но на самом деле ресурс не меняется , когда я использую фрагментацию для создания компонента . Ресурс не меняется.

Я останавливаюсь на FabArea.razor, чтобы проверить, изменилось ли нажатие кнопки или источник . Остановка при Нажатии кнопки.

Я попытался добавить StateHasChanged() в свой код , но это не помогло, когда изменился oResource .

oResource Изменен на B , по выбору Ресурс остается прежним.

По какой-то причине я должен превратить каждую «Область» ,»выделение» и «кнопку» в разные компоненты .

Вот Мой код .

Родительский компонент : DyResource.Razor

 @page "/DyResource"
<h3>DyResource</h3>
<p>You Just Select : @SelectedValue </p>
<p>isDefault Resource : @(isDefaultResource?"Default Value":"Not Default Value") </p>
<p>Resource[0]: @(oResource.First().id.ToString())</p>

<FabArea Componets="@liComponets"></FabArea>


@code {
    public List<iFabComponet> liComponets { get; set; }
    public List<Selection> oResource { get; set; }
    public string SelectedValue { get; set; }
    public bool isDefaultResource { get; set; } = true;
    public class Selection
    {
        public string id { get; set; }
        public string text { get; set; }
    }
    public class iFabComponet
    {
        public Type Type { get; set; }
        public string Row { get; set; }
        public string Length { get; set; }
        public string Seq { get; set; }
        public RenderFragment Control { get; set; }
        public Dictionary<string, object> Dic { get; set; }
        public object TComponent { get; set; }
    }
    protected override void OnInitialized()
    {
        DefaultResource();      //Set oResource
        CreateComponent();
    }

    //Selection Resource When First Render Pages
    private void DefaultResource()
    {
        oResource = new List<Selection>
            {
            new Selection { id = "A01", text = "A01" },
            new Selection { id = "A02", text = "A02" },
            new Selection { id = "A03", text = "A03" },
            new Selection { id = "A04", text = "A04" },
            new Selection { id = "A05", text = "A05" }
            };
        //StateHasChanged();
    }

    // Selection Resource When Button Click
    private void ChangedResource()
    {
        oResource = new List<Selection>()
            {
            new Selection { id = "B01", text = "B01" },
            new Selection { id = "B02", text = "B02" },
            new Selection { id = "B03", text = "B03" },
            new Selection { id = "B04", text = "B04" },
            new Selection { id = "B05", text = "B05" }
            };
        //StateHasChanged();
    }

    //Create KeyValuePair  for Child Components
    private void CreateComponent()
    {
        List<iFabComponet> FCs = new List<iFabComponet>();
        var DDLDic = new Dictionary<string, object>();
        DDLDic.Add("Label", "Type");
        DDLDic.Add("Resource", oResource);
        DDLDic.Add("TextField", "id");
        DDLDic.Add("ValueField", "text");
        DDLDic.Add("Enabled", true);
        DDLDic.Add("Id", "ddlType");
        DDLDic.Add("Width", "100%");
        DDLDic.Add("ResultValueChanged", EventCallback.Factory.Create<System.String>(this, str => TypeSelected(str)));
        iFabComponet FirstCom = new iFabComponet() { Type = typeof(FabDDL<string, Selection>), Row = "1", Length = "6", Seq = "1", Dic = DDLDic };
        liComponets.Add(FirstCom);


        var btnDic = new Dictionary<string, object>();
        btnDic.Add("ButtonTitle", "Get Data");
        btnDic.Add("isNeedPad", true);
        btnDic.Add("PadLength", 4);
        btnDic.Add("OnClick", EventCallback.Factory.Create<System.String>(this, str => BtnClick()));
        iFabComponet SecCom = new iFabComponet() { Type = typeof(FabButton), Row = "2", Length = "6", Seq = "2", Dic = btnDic };
        liComponets.Add(SecCom);
    }

    //Selection Event
    private void TypeSelected(string x)
    {
        SelectedValue = x;
    }

    //Button Event
    private void BtnClick()
    {
        if (isDefaultResource)
        {
            ChangedResource();
            isDefaultResource = false;
        }
        else
        {
            DefaultResource();
            isDefaultResource = true;
        }
        CreateComponent();
        StateHasChanged();
    }

}

 

FabArea.Razor (Area to show and Render Child Component)

 @using System.Linq.Expressions
<div class="card">
    <div class="card-body">
        @foreach (var item in Contents)
        {
            @item
            ;
        }
    </div>
</div>


@code {
    [Parameter]
    public List<iFabComponet> Componets { get; set; }

    public List<RenderFragment> Contents { get; set; }

    protected override void OnInitialized()
    {
        if (Componets.Count() > 0 amp;amp; Componets != null)
        {
            CreateFragment();
        }

    }
    public async void CreateFragment()
    {
        int iComponent = 0;
        List<RenderFragment> RFTs = new List<RenderFragment>();
        Contents = new List<RenderFragment>();
        int iContent = 1;
        foreach (var area in Componets)
        {
            RenderFragment renderFragment = (builder) =>
            {
                builder.OpenComponent(iComponent, area.Type);

                //Using For Checking Resource . 
                foreach (var item in area.Dic)
                {
                    var q = item.Key;
                    var w = item.Value;
                }
                builder.AddMultipleAttributes(iContent, area.Dic);

                builder.CloseComponent();
            };
            Contents.Add(renderFragment);
        }
        StateHasChanged();
    }
}
 

Here is Selection Component and Button Component .

FabDDL.razor

 @typeparam T
@typeparam TResource


<div class="row">
    <label class="col-md-2">@Label</label>
    <div class="col-md-5">
        <select class="selection" id="@id" disabled="@(!Enabled)" @onchange="@(() => ResultValueChanged.InvokeAsync())">
            <option></option>
            @if (Resource != null)
            {
                @foreach (var item in Resource)
                {
                    <option value="@(item.GetType().GetProperty(ValueField).GetValue(item))">@(item.GetType().GetProperty(TextField).GetValue(item))</option>
                }
            }
        </select>
    </div>
</div>
@code {
    [Parameter] public string Label { get; set; }
    //[Parameter] public T ResultValue { get; set; }
    [Parameter] public List<TResource> Resource { get; set; }
    [Parameter] public string DefaultText { get; set; } = "Select an Option";
    [Parameter] public string id { get; set; } = "DropDownList"   Guid.NewGuid().ToString();
    [Parameter] public string Width { get; set; } = "100 %";
    [Parameter] public bool Enabled { get; set; }
    [Parameter] public string TextField { get; set; }
    [Parameter] public string ValueField { get; set; }
    [Parameter] public EventCallback<T> ResultValueChanged { get; set; }
}

<style>
    .selection {
        width: 100%;
        height: 100%;
        padding-left: 15px;
    }
</style>

 

ФабБуттон.бритва

 @if (isNeedPad){<div class="@PadRowClass"></div>}

<div class="col-md-2 pt-3 middle">
    <button class="btn btn-info" type="@ButtonType" @onclick="@(() => OnClick.InvokeAsync())">@ButtonTitle</button>
</div>

@code {
    [Parameter] public string ButtonTitle { get; set; } = "Click ME!";
    [Parameter] public string ButtonType { get; set; } = "button";
    [Parameter] public EventCallback<string> OnClick { get; set; }
    [Parameter] public bool isNeedPad { get; set; } = false;
    [Parameter] public int PadLength { get; set; } = 1;
    public string PadRowClass { get; set; }

    protected override void OnInitialized()
    {
        PadRowClass = "col-md-"   PadLength.ToString();

        base.OnInitialized();
    }
}

 

Комментарии:

1. Это настоящая «стена кода». Не могли бы вы сократить его до чего-нибудь более удобного для чтения?

2. Привет, я согласен с @HenkHolterman. Я теряюсь в деталях. Можете ли вы свести это к простой демонстрационной странице, которая показывает, в чем ваша проблема?

3. Спасибо за ответ ,я зафиксировал это на github , я пытаюсь выяснить, могу ли я каким-либо образом изменить «ресурс выбора», когда этот выбор создается с помощью фрагментации. GitHub : github.com/humanbing2002/Blazor_Demo