0
votes

Routage angulaire Nativescript d'un module enfant à un autre dans une configuration Tabs

J'utilise une configuration <page-router-outlet></page-router-outlet> et <BottomNavigation></BottomNavigation> pour les onglets de mon projet Nativescript Angular, et j'ai du mal à naviguer d'un itinéraire d'onglet enfant vers un autre onglet enfant route.

Voici donc l' app-routing.module.ts :

        this.router.navigate([
            '../tabs', {
                outlets: { feedTab: ['feed'] }, relativeTo: this.activatedRoute
            }
        ]);

Et j'essaie actuellement de naviguer depuis le module de création d'onglets vers le module d'onglets de fil. Voici le create-routing.module.ts :

const routes: Routes = [
    { path: '', redirectTo: 'create', pathMatch: 'full' },
    { path: 'create', component: CreateComponent },
    { path: 'create-tasks', component: CreateTasksComponent },
    { path: 'create-preview', component: CreatePreviewComponent }
];

Donc, si je suis actuellement dans la route de create-preview , comment puis-je revenir à la sortie "onglets / flux" qui se trouve dans le app-routing.module.ts ?

J'ai essayé ceci:

const routes: Routes = [
    { path: '', redirectTo: '/auth', pathMatch: 'full' },
    { path: 'auth', component: AuthComponent },
    { path: 'individual-tasks', component: SpecificTasksComponent },
    {
        path: 'tabs',
        component: TabsComponent,
        children: [
            {
                path: 'feed',
                loadChildren: '~/app/pages/feed/feed.module#FeedModule',
                component: NSEmptyOutletComponent,
                outlet: 'feedTab'
            },
            {
                path: 'notification',
                loadChildren: '~/app/pages/notification/notification.module#NotificationModule',
                component: NSEmptyOutletComponent,
                outlet: 'notificationTab'
            },
            {
                path: 'create',
                loadChildren: '~/app/pages/create/create.module#CreateModule',
                component: NSEmptyOutletComponent,
                outlet: 'createTab'
            },
            {
                path: 'profile',
                loadChildren: '~/app/pages/profile/profile.module#ProfileModule',
                component: NSEmptyOutletComponent,
                outlet: 'profileTab'
            }
        ]
    }
];

mais même si j'écris explicitement que la navigation devrait être vers le feedTab, il navigue toujours vers la sortie de départ (profil) au lieu de la sortie d'alimentation. C'est comme si le point de vente indiqué était entièrement ignoré ... Des idées ???


3 commentaires

Je ne pense pas que le routeur vous donne la possibilité de changer d'onglet. Vous devrez mettre à jour selectedIndex de l'onglet, puis naviguer vers l'onglet particulier que vous aimez.


Je pense que @Manoj est correct ... Maintenant, je vais devoir trouver comment mettre à jour le selectedIndex à partir de l'un de ses composants enfants


Utilisez un service avec un sujet de comportement. Écoutez le sujet du composant parent, mettez à jour la valeur du composant enfant.


3 Réponses :


0
votes

Essaye ça :

Vous devez supprimer this.activatedRoute de navigate() , qui attribue la route actuelle avant le chemin de routage que vous avez fourni maintenant.

 this.router.navigate(['../tabs/feed', {
       outlets: {  primary: ['feed'], feedTab: ['feed'] }
    }
 ])

vous pouvez en savoir plus sur les outlets here de outlets here et suivre ce blog pour plus de détails .

J'espère que cela t'aides.. :)


0 commentaires

1
votes

Je ne pense pas que le routeur vous donne la possibilité de changer d'onglet. Vous devrez mettre à jour selectedIndex of BottomNavigation , puis accéder à l'onglet particulier que vous aimez.

Pour mettre à jour selectedIndex partir d'un composant enfant, utilisez un service avec un BehaviorSubject . Écoutez le sujet du composant parent, mettez à jour la valeur du composant enfant.


3 commentaires

Merci @Manoj qui a fonctionné et j'ai pu naviguer vers différents index avec le modèle BehaviorSubject ... Cependant, après la navigation, tout dans cet onglet dans lequel je navigue aussi a disparu. Donc, il montre juste une page blanche vierge après la navigation, mais si je navigue vers un autre onglet puis que je reviens, tous les composants reviennent et sont à nouveau visibles. Est-ce que ça sonne des cloches?


@WJosh Vetter Bonjour Manoj, Josh pouvez-vous clarifier le fonctionnement de la solution avec BehaviorSubject?


@LimyandiVicoTrico J'ai publié une réponse montrant comment BehaviorSubject fonctionne avec un exemple de code.



1
votes

L'un des commentaires a demandé de clarifier comment utiliser un BehaviorSubject à cette fin, je publierai donc ce code au cas où il pourrait aider quelqu'un à l'avenir. Cela montrera comment utiliser un BehaviorSubject rxjs pour écouter les changements d'onglets et fournira également un moyen de modifier l'onglet actuel de BottomNavigation de n'importe où dans l'application à l'aide de ce service.

Le but de ce service est de fournir un emplacement central où l'élément d'interface utilisateur BottomNavigation est accessible dans toute l'application. Ça peut:

  • Utilisez un ElementRef de BottomNavigation afin que le nativeElement soit accessible pour obtenir ou modifier l'onglet actuel de l'élément BottomNavigation .
  • Fournit une observable BehaviorSubject rxjs qui permet aux consommateurs de ce service de s'abonner aux événements BottomNavigation selectedIndexChanged puis d'être avertis. Les newIndex et oldIndex sont émis à partir de cet observable rxjs BehaviorSubject sur chaque événement BottomNavigation selectedIndexChanged .

REMARQUE: Dans le composant qui a l'élément BottomNavigation dans son modèle (app.component.ts dans cet exemple), il doit donner à ce NavigationService la référence au BottomNavigation il a besoin dans son ngAfterViewInit cycle de vie ngAfterViewInit comme: this._navigationService.bottomNavigationRef = this.navRef; (voir l'extrait dans app.component.ts ci-dessous)

// another.component.ts

import { Component, OnDestroy, OnInit } from '@angular/core';

import { Subscription } from 'rxjs';

import { NavigationService } from './navigation.service';

@Component({
  selector: 'app-another-component',
  templateUrl: './another.component.html',
  styleUrls: ['./another.component.scss']
})
export class AnotherComponent implements OnDestroy, OnInit {
  private _subscription: Subscription;

  constructor(private _navigationService: NavigationService) {}

  ngOnInit(): void {
    // Example using BehaviorSubject Observable:
    this._subscription = this._navigationService.bottomNavigationTab$.subscribe(
      (selectedTab) => {
        console.log(`This component knows that the BottomNavigation current tab is now: ${selectedTab.newIndex} and the old tab was: ${selectedTab.oldIndex}`);

        if (selectedTab.newIndex === 2) {
          // do something ...
        }
      }
    );
  }

  ngOnDestroy(): void {
    // unsubscribe from BehaviorSubject Observable
    this._subscription.unsubscribe();
  }

  // Example changing the BottomNavigation tab from another component:
  changeTab(tab: number): void {
    this._navigationService.bottomNavigationRef.nativeElement.selectedIndex = tab;
  }

}
<!-- app.component.html (partial file just to show #bottomNav) -->
<BottomNavigation #bottomNav>
<!-- ... -->
</BottomNavigation>
// app.component.ts (partial file)

// ...
 @ViewChild('bottomNav') navRef: ElementRef<BottomNavigation>;
// ...
ngAfterViewInit(): void {
    // Gives the NavigationService the reference to the BottomNavigation it needs.
    this._navigationService.bottomNavigationRef = this.navRef;
}
// ...
// navigation.service.ts

import { ElementRef, Injectable, OnDestroy } from '@angular/core';

import { BottomNavigation, SelectedIndexChangedEventData } from '@nativescript/core';

import { BehaviorSubject, Subscription } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class NavigationService implements OnDestroy {
  private _bottomNavigationRef: ElementRef<BottomNavigation>;
  private _subscription: Subscription;
  private callbackSelIndexChgEv;
  /** rxjs BehaviorSubject observable to track the current tab of the BottomNavigation */
  bottomNavigationTab$: BehaviorSubject<{ newIndex: number; oldIndex: number }>;

  constructor() {
    // Must initialize rxjs BehaviorSubject observable with initial value.
    this.bottomNavigationTab$ = new BehaviorSubject({
      newIndex: -1,
      oldIndex: -1,
    });

    // Logs the current tab per this service.
    this._subscription = this.bottomNavigationTab$.subscribe((value) => {
      console.log(
        `NavigationService -> The BottomNavigation current tab index is now:
            newIndex: "${value.newIndex}"
            oldIndex: "${value.oldIndex}"`
      );
    });
  }

  ngOnDestroy(): void {
    this._subscription.unsubscribe();
    this._bottomNavigationRef.nativeElement.off(
      BottomNavigation.selectedIndexChangedEvent,
      this.callbackSelIndexChgEv
    );
  }

  get bottomNavigationRef(): ElementRef<BottomNavigation> {
    return this._bottomNavigationRef;
  }

  set bottomNavigationRef(bottomNavRef: ElementRef<BottomNavigation>) {
    this._bottomNavigationRef = bottomNavRef;

    this.callbackSelIndexChgEv = (
      $event: SelectedIndexChangedEventData
    ): void => {
      /* Update the current tab of the rxjs BehaviorSubject Observable */
      this.bottomNavigationTab$.next({
        newIndex: $event.newIndex,
        oldIndex: $event.oldIndex,
      });
    };

    this._bottomNavigationRef.nativeElement.on(
      BottomNavigation.selectedIndexChangedEvent,
      this.callbackSelIndexChgEv
    );
  }
}


Documentation de rxjs BehaviorSubject : https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject


0 commentaires