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) @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> <TabTemplate>
@if (Type == TabType.Line && item.Closable) @if (Type == TabType.Line && item.Closable)
{ {
@ -35,23 +35,27 @@
@* <MenuItem OnClick="@(()=>{ ReuseTabsService.Pin(item.Url);})">@Locale.PinTab</MenuItem> *@ @* <MenuItem OnClick="@(()=>{ ReuseTabsService.Pin(item.Url);})">@Locale.PinTab</MenuItem> *@
</Menu> </Menu>
</TabContextMenu> </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> </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.Init(true);
ReuseTabsService.OnStateHasChanged += OnStateHasChanged; ReuseTabsService.OnStateHasChanged += OnStateHasChanged;
RouteData ??= ReuseTabsRouteData?.RouteData; LoadPage();
ReuseTabsService.TrySetRouteData(RouteData, true);
base.ChildContent = RenderPanes; base.ChildContent = RenderPanes;
ActiveKey = ReuseTabsService.ActiveKey; ActiveKey = ReuseTabsService.ActiveKey;
} }
private void LoadPage()
{
RouteData ??= ReuseTabsRouteData?.RouteData;
ReuseTabsService.TrySetRouteData(RouteData, true);
}
protected override bool ShouldRender() => !InReusePageContent && base.ShouldRender(); 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) protected override void Dispose(bool disposing)
{ {
ReuseTabsService.OnStateHasChanged -= OnStateHasChanged; ReuseTabsService.OnStateHasChanged -= OnStateHasChanged;
@ -125,9 +141,7 @@ namespace AntDesign
{ {
UpdateTabsPosition(); UpdateTabsPosition();
RouteData ??= ReuseTabsRouteData?.RouteData; LoadPage();
ReuseTabsService.TrySetRouteData(RouteData, true);
ActivatePane(ReuseTabsService.ActiveKey); ActivatePane(ReuseTabsService.ActiveKey);
} }

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

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

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

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

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

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