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)
|
@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))
|
||||||
|
|
Загрузка…
Ссылка в новой задаче