반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발꿈나무

[Blazor] Telerik - TabStrip에서 호출한 razor Page Reload 하기 본문

C#/Telerik

[Blazor] Telerik - TabStrip에서 호출한 razor Page Reload 하기

HYOKYE0NG 2021. 12. 2. 09:29
반응형

진짜 거의 2주동안 삽질했던,, 젤 힘들었던 razor page reload,,

다음엔 삽질 하지 말라고 기록해둔다,, 부들부들

 

 

내가 해결해야 했던 상황을 먼저 설명해보자.

Part.razor 파일에는 Telerik Grid가 있고, 이 grid의 row를 클릭할 경우

해당 row의 데이터를 가지고 Cad.razor라는 파일을 Tabstrip의 content로 뿌린다.

이 때, tabstrip에 내용이 있고(grid의 row가 클릭되어 있고), 다른 row를 클릭할 때 tabstrip의 내용이 바뀌어야 한다.

 

 

아래의 사진은 처음 grid의 row를 클릭했을 경우이다.

1203907이라는 데이터를 가진 row를 클릭했고, 이에 따라 1203907의 Cad List가 잘 출력되었다.

그리고 이 상태에서 11203840이라는 데이터를 가진 row를 클릭하면,

11203840에 해당하는 Cad List가 출력되어야 하지만 이전에 클릭되었던

120397의 Cad List가 출력된다.

즉, 아래의 Cad.razor page가 reload 되지 않는다는 것이다.

 

 

코드를 살펴보자

 

우선 Part.razor 파일에서 Cad.razor Page를 호출하는 소스코드이다.

 

위의 TelerikGrid에서 OnRowClick event로 RowClickHandler 메소드를 호출한다.

이 RowClickHandler에서 클릭한 row의 데이터를 DctNo, PartNo라는 변수에 저장하고,

이 변수들이 NULL이 아닐 경우 인수로 넘겨 TabStrip에서 Cad.razor 파일을 호출한다.

<TelerikGrid Data="@GridData" TotalCount="@Total" OnRead="@ReadItems"
             Sortable="true"
             SortMode="@SortMode.Single"
             FilterMode="@GridFilterMode.FilterMenu"
             Pageable="true"
             PageSize="20"
             SelectionMode="GridSelectionMode.Multiple"
             OnRowClick="@RowClickHandler">
    <GridColumns>
        <GridColumn Field="@nameof(V_PART.DCN_NO)" Title="DCN No." Lockable="true" />
        <GridColumn Field="@nameof(V_PART.DCT_NO)" Title="DCT No." Lockable="true" />
        <GridColumn Field="@nameof(V_PART.S_PART_NO)" Title="Part No." Lockable="true" />
    </GridColumns>
</TelerikGrid>

<TelerikTabStrip @bind-ActiveTabIndex="@ActiveTabIndex">
    <TabStripTab Title="Detail_Info">
        <div class="detail">
		</div>
    <TabStripTab Title="Cad">
        @if (DctNo != null && PartNo != null)
        {
            <Cad DCT_NO="@DctNo" ENV_NO="@PartNo"></Cad>
        }
    </TabStripTab>
</TelerikTabStrip>


@code{
	public List<V_PART> GridData { get; set; }
    public List<V_PART> SourceData { get; set; }
    public int Total { get; set; } = 0;

	public int ActiveTabIndex { get; set; } = 0;
    public string DctNo { get; set; }
    public string PartNo { get; set; }
    
    protected async override void OnInitialized()
    {
        SourceData = await EnvironmentService.GetPart();
    }

    protected void ReadItems(GridReadEventArgs args)
    {
        var datasourceResult = SourceData.ToDataSourceResult(args.Request);
        GridData = (datasourceResult.Data as IEnumerable<V_PART>).ToList();
        Total = datasourceResult.Total;

        StateHasChanged();
    }
    
    private async void RowClickHandler(GridRowClickEventArgs args)
    {
        V_PART item = args.Item as V_PART;
        DctNo = item.DCT_NO;
        PartNo = item.S_PART_NO;

        StateHasChanged();
    }
}

 

 

 

TabStrip의 content를 담당하는 Cad.razor 파일의 코드는 다음과 같았다.(과거형)

 

Part.razor에서 파라미터로 받은 DCT_NO, ENV_NO를 가지고 CadList를 가져온 후

TelerikGrid에 뿌리는 간단한 페이지다.

하지만 이 상황에서는 파라미터가 제대로 넘어오긴 하지만

OnInitialized(), ReadItems() 메소드가 실행되지 않았다.

<TelerikGrid Data="@GridData" TotalCount="@Total" OnRead="@ReadItems"
             Sortable="true"
             SortMode="@SortMode.Single"
             Pageable="true"
             PageSize="10"
             Width="1600px"
             ScrollMode="@GridScrollMode.Scrollable">
    <GridColumns>
        <GridColumn Field="@nameof(W_CAD.DCN_NO)" Title="DCN No." Lockable="true" Width="100px" />
        <GridColumn Field="@nameof(W_CAD.DCT_NO)" Title="DCT No." Lockable="true" Width="150px" />
    </GridColumns>
</TelerikGrid>


@Code{
	[Parameter] public string DCT_NO { get; set; }
    [Parameter] public string ENV_NO { get; set; }

	public List<W_CAD> SourceData { get; set; }
    public List<W_CAD> GridData { get; set; }
    public int Total { get; set; } = 0;
    

	protected async override void OnInitialized()
    {
        SourceData = await ObjectService.GetCadList(DCT_NO, ENV_NO);
    }
        
	protected void ReadItems(GridReadEventArgs args)
    {
        var datasourceResult = SourceData.ToDataSourceResult(args.Request);
        GridData = (datasourceResult.Data as IEnumerable<W_CAD>).ToList();
        Total = datasourceResult.Total;

        StateHasChanged();
    }
}

 

 

삽질의 결과 우선 OnInitialized()를 OnParametersSetAsync()로 바꿔야 했다.

OnInitialized()는 말 그대로 처음 초기화될 때 실행되는 메소드이고,

OnParametersSetAsync() 메소드는 파라미터가 실행될 때마다 실행되는 메소드이다.

 

상세한 내용은 아래의 페이지를 참고하였다.

 

Blazor Observable Collection | Telerik UI for Blazor

 

docs.telerik.com

 

OnParametersSetAsync()메소드로 변경했더니 파라미터가 바뀔 때마다 실행되어 SourceData는 잘 가져왔다.

하지만, ReadItems() 메소드는 여전히 실행되지 않아 grid의 데이터가 바뀌지 않았다.

 

2차 삽질의 결과 grid 자체의 parameter가 변경되지 않아 그리드가 다시 렌더링되지 않기 때문에

OnRead를 실행하지 않는 것이었다.

그래서 현재 DataSourceRequest 개체를 cache하고, 이 개체를 사용하여 OnParametersSetAsync에서 호출할 수 있는

별도의 메소드로 데이터를 가져와야 했다.

 

상세한 내용은 아래의 페이지를 참고하였다. 

 

Blazor Grid - Manual Operations | Telerik UI for Blazor

By default, the grid will receive the entire collection of data, and it will perform the necessary operations (like paging, sorting, filtering) internally to it. You can perform these operations yourself by handling the OnRead event of the grid as shown in

docs.telerik.com

 

최종 소스코드는 다음과 같다.

 

우선 OnInitialized()를 OnParametersSetAsync()로 바꾸고

ReadItems()에서 현재의 request를 저장한 후

SetGridData() 메소드에서 ReadItems에서 저장한 request를 바탕으로 GridData를 변경하였다.

<TelerikGrid Data="@GridData" TotalCount="@Total" OnRead="@ReadItems"
             Sortable="true"
             SortMode="@SortMode.Single"
             Pageable="true"
             PageSize="10"
             Width="1600px"
             ScrollMode="@GridScrollMode.Scrollable">
    <GridColumns>
        <GridColumn Field="@nameof(W_CAD.DCN_NO)" Title="DCN No." Lockable="true" Width="100px" />
        <GridColumn Field="@nameof(W_CAD.DCT_NO)" Title="DCT No." Lockable="true" Width="150px" />
    </GridColumns>
</TelerikGrid>


@Code{
	[Parameter] public string DCT_NO { get; set; }
    [Parameter] public string ENV_NO { get; set; }

	public List<W_CAD> SourceData { get; set; }
    public List<W_CAD> GridData { get; set; }
    public int Total { get; set; } = 0;
    
    public DataSourceRequest CurrentRequest { get; set; }
    

	protected override async Task OnParametersSetAsync()
    {
        SourceData = await ObjectService.GetCadList(DCT_NO, ENV_NO);
        SetGridData();
    }
        
	protected void ReadItems (GridReadEventArgs args)
    {
        CurrentRequest = args.Request;
        SetGridData();
    }

    private void SetGridData()
    {
        if (CurrentRequest == null)
        {
            return;
        }

        var datasourceResult = SourceData.ToDataSourceResult(CurrentRequest);
        GridData = (datasourceResult.Data as IEnumerable<W_CAD>).ToList();
        Total = datasourceResult.Total;
    }
}

 

엄청난 삽질의 결과 정리끝!

반응형
Comments