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:
Родитель
d2f5a1a8c1
Коммит
2793e5a8ff
|
@ -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))
|
||||
|
|
Загрузка…
Ссылка в новой задаче