web-dev-qa-db-fra.com

Ionic 2: EXCEPTION: Aucun fournisseur pour NavController

j'ai un problème avec mon ionic 2/angular 2 app.

J'ai obtenu un app.ts où la partie "auth" du trou est mise en œuvre.

Le code ressemble à ceci:

 import {Nav, Platform, Modal, ionicBootstrap} from "ionic-angular";
import {NavController} from "ionic-angular/index";
import {StatusBar} from "ionic-native";
import {Component, ViewChild} from "@angular/core";
import {AngularFire, FirebaseListObservable, FIREBASE_PROVIDERS, defaultFirebase} from "angularfire2";
import {HomePage} from "./pages/home/home";
import {AuthPage} from "./pages/auth/home/home";

@Component({
  templateUrl: "build/app.html",
})

class MyApp {
  @ViewChild(Nav) nav: Nav;

  authInfo: any;
  rootPage: any = HomePage;
  pages: Array<{title: string, component: any}>;

  constructor(private platform: Platform, private navCtrl: NavController, private af: AngularFire) {
    this.initializeApp();

    this.pages = [
      { title: "Home", component: HomePage }
    ];

  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
    });
  }

  openPage(page) {
    this.nav.setRoot(page.component);
  }

  ngOnInit() {
    this.af.auth.subscribe(data => {
      if (data) {
        this.authInfo = data;
      } else {
        this.authInfo = null;
        this.showLoginModal();
      }
    });
  }

  logout() {
    if (this.authInfo) {
      this.af.auth.logout();
      return;
    }
  }

  showLoginModal() {
    let loginPage = Modal.create(AuthPage);
    this.navCtrl.present(loginPage);
  }
}

Mais maintenant, lorsque j'essaie d'exécuter l'application, je reçois ce message:

ORIGINAL EXCEPTION: No provider for NavController

Avez-vous une idée de la façon de résoudre ce problème? Merci!

15
Fargho

Vous ne pouvez pas injecter un NavController dans un composant Root via un constructeur.

Donc, fondamentalement, vous pouvez not faire quelque chose comme ci-dessous: -

constructor(private nav: NavController){
}

Voici comment injecter un NavController

@Controller({
  ....
})
class MyApp{
  @ViewChild('nav') nav: NavController;
  ....
  ....
  constructor(...){ // See, no NavController here
  }
  ....
}

Et c'est ce que Ionic docs a à dire.

Que faire si vous souhaitez contrôler la navigation à partir de votre composant d'application racine? Vous ne pouvez pas injecter NavController car tous les composants qui sont des contrôleurs de navigation sont des enfants du composant racine et ne sont donc pas disponibles pour être injectés.

En ajoutant une variable de référence à l'ion-nav, vous pouvez utiliser @ViewChild pour obtenir une instance du composant Nav, qui est un contrôleur de navigation (il étend NavController)

19
Mav55

Vous ne pouvez pas injecter le NavController dans votre composant racine , vous devez donc le supprimer de cette partie du code. De plus amples informations peuvent être trouvées ici.

Veuillez vous assurer que vous disposez déjà d'une variable de référence dans votre ion-nav, comme ceci (le #myNav):

<ion-nav #myNav [root]="rootPage"></ion-nav>

Et puis vous pouvez obtenir cette référence en utilisant ViewChild. Vous pouvez ensuite simplement accéder à une autre page, en utilisant cette propriété:

import { Nav, Platform, ... } from "ionic-angular";
// more imports...
// ...

@Component({
  templateUrl: "build/app.html"
})

class MyApp {
  @ViewChild('myNav') nav: NavController // <--- Reference to the Nav

  authInfo: any;
  rootPage: any = HomePage;
  pages: Array<{title: string, component: any}>;

  // Remove the "navCtrl: NavController" from the constructor, since
  // now your getting the reference from the view
  constructor(private platform: Platform, private af: AngularFire) {
    this.initializeApp();

    this.pages = [
      { title: "Home", component: HomePage }
    ];

  }

  // ...

  openPage(page) {
    // this.navCtrl.setRoot(page.component); <-- Wrong!
    this.nav.setRoot(page.component) // <-- Right! Use the this.nav property
  }

  // ...
}
15
sebaferreras

Il est recommandé d'utiliser this.app.getActiveNavs() dans Ionic 3+ car getActiveNav () sera supprimé dans la prochaine version majeure, afin que votre fonction puisse être écrite comme suit:

showLoginModal() {
    let loginPage = Modal.create(AuthPage);
    this.getActiveNavs().slice(-1)[0].present(loginPage);
}

Pour pousser sur la pile de navigation, vous pouvez simplement importer la page (disons YourPage) puis:

this.getActiveNavs()[0].Push(YourPage);

Ancien comportement, pour Ionic 2, obsolète dans Ionic 3:

Vous pouvez utiliser this.getActiveNav() dans Ionic 2 (et Ionic 3), de sorte que votre fonction peut être écrite comme suit:

showLoginModal() {
    let loginPage = Modal.create(AuthPage);
    this.getActiveNav().present(loginPage);
}

Avec l'une ou l'autre méthode, vous n'avez besoin d'aucune variable import ou private pour que cela fonctionne. Si vous êtes dans un Component, référez-vous simplement à votre App:

import {App} from 'ionic-angular';
import {MyPage} from '../pages/my/page';

@Component()
export class MyComponent {
    constructor(private app: App) {
    }
    goToMyPage() {
        this.app.getActiveNav().Push(MyPage);
    }
}
8
Yvan

Je l'ai manipulé avec:

import { App, NavController } from 'ionic-angular';

constructor(protected app: App) {
... }

get navCtrl(): NavController {
    return this.app.getRootNav();
}

Réponse tirée d'ici: problèmes github

2
V. Aliosha

Ok, je viens d'utiliser la navigation au lieu de NavigationController et maintenant cela fonctionne.

2
Fargho

Vous avez mal nommé votre nav;

this.nav.setRoot(page.component);

Devrait être

this.navCtrl.setRoot(page.component);

Et vérifiez si vous importez correctement

import { NavController} from 'ionic-angular';
1
LeRoy

L'une des causes de cette erreur est lorsque vous essayez d'injecter NavController dans une classe de fournisseur.
Comme ça:

@Injectable()
export class MyProviderService {

  constructor(private nav: NavController){
  }
}

Je viens d'avoir cette erreur ...
Après avoir supprimé cette injection (et refactorisé le code), cela a bien fonctionné.

0
Ricardo Silva