pref(module: tabs): make tab pane only render once (#4255)

* pref(module: tabs): render pane content only once

* fix reuse tabs content delay

* fix reusetabs reload

* fix title reload and update

* refactor
This commit is contained in:
James Yeung 2024-10-09 18:57:31 +08:00 коммит произвёл GitHub
Родитель d2f5a1a8c1
Коммит 2793e5a8ff
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 55 добавлений и 41 удалений

Просмотреть файл

@ -14,7 +14,7 @@
{
@foreach (var item in ReuseTabsService.Pages)
{
<TabPane Id="@item.Url" @key="@item.Key" Key="@item.Key" Class="@TabPaneClass" Closable="item.Closable" ForceRender>
<TabPane Id="@item.Url" @key="@item.Key" Key="@item.Key" Class="@TabPaneClass" Closable="item.Closable" ForceRender ChildContent="@PaneConent(item)">
<TabTemplate>
@if (Type == TabType.Line && item.Closable)
{
@ -35,23 +35,27 @@
@* <MenuItem OnClick="@(()=>{ ReuseTabsService.Pin(item.Url);})">@Locale.PinTab</MenuItem> *@
</Menu>
</TabContextMenu>
<ChildContent>
@if (!HidePages && item.Rendered)
{
item.Body ??= @<AntDesign.Core.Internal.KeepAlive ChildContent="Body" ></AntDesign.Core.Internal.KeepAlive>;
if (TabPaneTemplate != null)
{
@TabPaneTemplate(item)
}
else
{
@item.Body
}
}
</ChildContent>
</TabPane>
}
}
}
private RenderFragment PaneConent(ReuseTabsPageItem item)
{
if (!HidePages && item.Rendered)
{
item.Body ??=@<AntDesign.Core.Internal.KeepAlive ChildContent="@Body" ></AntDesign.Core.Internal.KeepAlive> ;
if (TabPaneTemplate != null)
{
return TabPaneTemplate(item);
}
else
{
return item.Body;
}
}
return null;
}
}

Просмотреть файл

@ -84,17 +84,33 @@ namespace AntDesign
ReuseTabsService.Init(true);
ReuseTabsService.OnStateHasChanged += OnStateHasChanged;
RouteData ??= ReuseTabsRouteData?.RouteData;
ReuseTabsService.TrySetRouteData(RouteData, true);
LoadPage();
base.ChildContent = RenderPanes;
ActiveKey = ReuseTabsService.ActiveKey;
}
private void LoadPage()
{
RouteData ??= ReuseTabsRouteData?.RouteData;
ReuseTabsService.TrySetRouteData(RouteData, true);
}
protected override bool ShouldRender() => !InReusePageContent && base.ShouldRender();
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
// reload current page after ReloadPage() was called by ReuseTabsService
if (ReuseTabsService.CurrentPage.Rendered == false)
{
LoadPage();
StateHasChanged(); // update title need calling render again
}
}
protected override void Dispose(bool disposing)
{
ReuseTabsService.OnStateHasChanged -= OnStateHasChanged;
@ -125,9 +141,7 @@ namespace AntDesign
{
UpdateTabsPosition();
RouteData ??= ReuseTabsRouteData?.RouteData;
ReuseTabsService.TrySetRouteData(RouteData, true);
LoadPage();
ActivatePane(ReuseTabsService.ActiveKey);
}

Просмотреть файл

@ -21,6 +21,8 @@ namespace AntDesign
internal event Action OnStateHasChanged;
private ReuseTabsPageItem _currentPage;
internal string CurrentUrl
{
get => "/" + _navmgr.ToBaseRelativePath(_navmgr.Uri);
@ -68,6 +70,8 @@ namespace AntDesign
_menusService.MenuItemLoaded += StateHasChanged;
}
internal ReuseTabsPageItem CurrentPage => _currentPage;
/// <summary>
/// Create a tab without navigation, the page doesn't really render until the tab is clicked
/// </summary>
@ -189,15 +193,15 @@ namespace AntDesign
{
url ??= CurrentUrl;
var reuseTabsPageItem = _pages?.FirstOrDefault(w => w.Url == url);
if (reuseTabsPageItem != null)
reuseTabsPageItem.Body = null;
reuseTabsPageItem.Title = null;
reuseTabsPageItem.Rendered = false;
// only reload current page, and other page would be load by tab navigation
if (reuseTabsPageItem?.Key == ActiveKey)
{
// Reset content
reuseTabsPageItem.Body = null;
// auto reload current page, and other page would be load by tab navigation
if (ActiveKey == reuseTabsPageItem.Key)
ActiveKey = reuseTabsPageItem.Key;
StateHasChanged();
}
StateHasChanged();
}
/// <summary>
@ -262,6 +266,8 @@ namespace AntDesign
}
ActiveKey = reuseTabsPageItem.Key;
_currentPage = reuseTabsPageItem;
OnStateHasChanged?.Invoke();
}

Просмотреть файл

@ -83,10 +83,10 @@
role="tabpanel"
aria-hidden="@(_isActive ? "false" : "true")"
aria-labelledby="@($"rc-tabs-{Id}-tab-{Key}")">
@if (_isActive || _hasRendered || ForceRender)
@if (ChildContent != null && (_isActive || _hasRendered || ForceRender))
{
_hasRendered = true;
@ChildContent
<AntDesign.Core.Internal.KeepAlive ChildContent="ChildContent"></AntDesign.Core.Internal.KeepAlive>
}
</div>
}

Просмотреть файл

@ -97,16 +97,6 @@ namespace AntDesign
Parent?.AddTabPane(this);
}
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
if (HasTabTitle)
{
_hasRendered = true;
}
}
public override async Task SetParametersAsync(ParameterView parameters)
{
if (parameters.IsParameterChanged(nameof(Tab), Tab))