Ionic 2: EXCEPTION: No provider for NavController

谁说胖子不能爱 提交于 2019-12-10 12:30:37

问题


i have a problem with my ionic 2/angular 2 app.

I got an app.ts where the hole "auth" part is implementet.

The code looks like this:

 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);
  }
}

But now, when i try to run the app i get this message:

ORIGINAL EXCEPTION: No provider for NavController

Do you have any idea how to solve this problem? Thanks!


回答1:


You can not inject a NavController in a Root component via a constructor.

So, basically you can not do something like below:-

constructor(private nav: NavController){
}

This is how you can inject a NavController

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

And this is what Ionic docs has to say.

What if you want to control navigation from your root app component? You can't inject NavController because any components that are navigation controllers are children of the root component so they aren't available to be injected.

By adding a reference variable to the ion-nav, you can use @ViewChild to get an instance of the Nav component, which is a navigation controller (it extends NavController)




回答2:


You can't inject the NavController in your Root Component so you should remove it from that part of the code. Further information can be found here.

Please make sure you already have a reference variable in your ion-nav, like this (the #myNav):

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

And then you can get that reference by using ViewChild. You can then just navigate to another page, by using that property:

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
  }

  // ...
}



回答3:


It's recommended you use this.app.getActiveNavs() in Ionic 3+ as getActiveNav() will be removed in the next major release, so your function can be written as:

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

To push on the nav stack, you can just import the page (say YourPage) then:

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

Old behaviour, for Ionic 2, deprecated in Ionic 3:

You can use this.getActiveNav() in Ionic 2 (and Ionic 3), so your function can be written as:

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

With either method you don't need any import or private variable for this to work. If you're in a Component, just refer to your 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);
    }
}



回答4:


Ok, i just used the nav instead of NavigationController and now it works.




回答5:


I handled it with:

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

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

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

Answer taken from here: github issues




回答6:


You named your nav incorrectly;

this.nav.setRoot(page.component);

Should be

this.navCtrl.setRoot(page.component);

And double check if your importing correctly

import { NavController} from 'ionic-angular';



回答7:


One cause for this error is when you try to inject NavController into a provider class.
Like this:

@Injectable()
export class MyProviderService {

  constructor(private nav: NavController){
  }
}

I just had that error...
After removing this injection (and refactoring the code), it worked fine.



来源:https://stackoverflow.com/questions/38121961/ionic-2-exception-no-provider-for-navcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!