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!
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)
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
}
// ...
}
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);
}
}
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
Ok, je viens d'utiliser la navigation au lieu de NavigationController et maintenant cela fonctionne.
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';
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é.