Reputation: 890
I am implementing app with nativescipt. I have added BottomNavigation (by following some examples on internet) with lazyLoading and going to to same with Tab component in child pages. Code looks like this
export const routes: Routes = [
{
path: '',
redirectTo: '/(searchTab:search//contactsTab:contacts//accountTab:account)',
pathMatch: 'full'
},
{
path: 'search',
component: NSEmptyOutletComponent,
loadChildren: () => import('@src/app/components/search/search.module').then((m) => m.SearchModule),
outlet: 'searchTab',
},
{
path: 'contacts',
component: NSEmptyOutletComponent,
loadChildren: () => import('@src/app/components/contacts/contacts.module.tns').then((m) => m.InquiriesModule),
outlet: 'inquiriesTab',
},
{
path: 'account',
component: NSEmptyOutletComponent,
loadChildren: () => import('@src/app/components/account/account.module').then((m) => m.AccountModule),
outlet: 'accountTab',
}
];
and standard HTML (will not copy here because it can be found in NS documentation)
However, according to NS documentation, -
Preloading: At least 1 to the sides (because of the swipe gesture) https://docs.nativescript.org/angular/ui/ng-components/tabs
I have expected that only side tabs will be preloadd but account tab is the third... I would accept that behaviour because lazyLoading at least would be usefull for some tabs but i have added console.log() to all 3 tab components and all of them were triggered. I hava read that this behaviour can be controlled in TabView by canging 'androidOffscreenTabLimit' property
so questions follows: 1) How can i control preloading behaviour for BottomNavigation and Tab 2) Can i disable preloading at all? 3) And what word 'at least 1 to the side' means?
Thanks in advance.
Upvotes: 0
Views: 816
Reputation: 91
I managed to do this with ngOnChanges() lifecyclehook in the component which should be loaded on tab icon click. (for my case its notification component)
Tab component View
<TabContentItem>
<StackLayout>
<user-notification
[tabindexes]="selectedTabIndex"
(readNotificationEvent)="doneReadNotifications($event)"></user-notification>
</StackLayout>
</TabContentItem>
SelectedTabIndex will get updated on tab changes. Tab component TS
selectedIndexChanged(event) {
this.selectedTabIndex = event.newIndex;
console.log("Index Changed : " + JSON.stringify(event.newIndex));
console.log("Selected Index " + this.selectedTabIndex);
}
Notification component TS file.
ngOnChanges(){
console.log("\nNotificationsOn Changes is called" + this.tabindexes);
// here you can write your code which needs to be called only when this tab is switched.
}
This is just a workaround, hope it's clear. really sorry bad documentation though...
Upvotes: 0
Reputation: 21908
With Tabs component at least the current tab and next / previous tabs are preloaded. You may avoid preloading if you BottomNavigation instead.
Also when you use Angular & lazy loading, the path for each outlet is generally set at once which will load all modules at once. To avoid this you may set the path only for primary outlet initially, then set path for other outlets as user change tabs. But this could a overhead, if the purpose behind is to know when the tab is actually getting rendered then you may simply use loaded
event.
HTML
<TabContentItem>
<GridLayout rows="0, *, auto, auto" (loaded)="onLoaded(1)">
<page-router-outlet name="searchTab" row="1" rowSpan="2"
actionBarVisibility="never">
</page-router-outlet>
<Label row="2" class="shadow"></Label>
<Label row="3" class="bottom-border"></Label>
</GridLayout>
</TabContentItem>
<TabContentItem>
<GridLayout rows="0, *, auto, auto" (loaded)="onLoaded(2)">
<page-router-outlet name="accountTab" row="1" rowSpan="2"
actionBarVisibility="never">
</page-router-outlet>
<Label row="2" class="shadow">
</Label>
<Label row="3" class="bottom-border"></Label>
</GridLayout>
</TabContentItem>
<TabContentItem>
<GridLayout rows="0, *, auto, auto" (loaded)="onLoaded(3)">
<page-router-outlet name="thirdTab" row="1" rowSpan="2"
actionBarVisibility="never">
</page-router-outlet>
<Label row="2" class="shadow"></Label>
<Label row="3" class="bottom-border"></Label>
</GridLayout>
</TabContentItem>
TS
onLoaded(index) {
console.log(`Tab ${index} loaded`);
}
Note: loaded event could be triggered every time when you visit the tab, if you are planning to make API calls here then you might want to add conditions to ensure if you have already loaded data.
Upvotes: 1