Ионный 2: ИСКЛЮЧЕНИЕ: Нет провайдера для NavController

У меня проблема с моим ионным 2/угловым 2 приложением.

Я получил app.ts, где часть отверстия "auth" реализована.

Код выглядит так:

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

Но теперь, когда я пытаюсь запустить приложение, я получаю это сообщение:

ORIGINAL EXCEPTION: No provider for NavController

Вы не знаете, как решить эту проблему? Благодарю!

Ответы

Ответ 1

Вы не можете вводить NavController в корневой компонент через конструктор.

Итак, в основном вы not можете сделать что-то вроде:

constructor(private nav: NavController){
}

Вот как вы можете вводить NavController

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

И это то, что должны сказать ионические документы.

Что делать, если вы хотите контролировать навигацию из вашего корневого компонента приложения? Вы не можете вводить NavController, потому что любые компоненты, которые являются навигационными контроллерами, являются дочерними элементами корневого компонента, поэтому они недоступны для ввода.

Добавив контрольную переменную в ion-nav, вы можете использовать @ViewChild для получения экземпляра компонента Nav, который является навигационным контроллером (он расширяет NavController)

Ответ 2

Вы не можете вводить NavController в свой корневой компонент, поэтому вы должны удалить его из этой части кода. Дополнительную информацию можно найти здесь.

Убедитесь, что у вас уже есть эталонная переменная в вашем ion-nav, например (#myNav):

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

И тогда вы можете получить эту ссылку, используя ViewChild. Затем вы можете просто перейти на другую страницу, используя это свойство:

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

Он рекомендовал использовать this.app.getActiveNavs() в Ionic 3+, поскольку getActiveNav() будет удален в следующем главном выпуске, поэтому ваша функция может быть записана как:

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

Чтобы надавить на навигационный стек, вы можете просто импортировать страницу (например, YourPage):

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

Старое поведение, для Ionic 2, устарело в Ionic 3:

Вы можете использовать this.getActiveNav() в Ionic 2 (и Ionic 3), поэтому ваша функция может быть записана как:

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

С помощью любого метода вам не нужна import или private переменная, чтобы это работало. Если вы находитесь в Component, просто обратитесь к своему 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

Хорошо, я просто использовал навигацию вместо NavigationController, и теперь она работает.

Ответ 5

Я обработал это с помощью:

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

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

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

Ответ отсюда: проблемы github

Ответ 6

Вы неправильно указали свой навигатор;

this.nav.setRoot(page.component);

Должно быть

this.navCtrl.setRoot(page.component);

И дважды проверьте правильность импорта

import { NavController} from 'ionic-angular';

Ответ 7

Одна из причин этой ошибки заключается в том, что вы пытаетесь внедрить NavController в класс поставщика.
Как это:

@Injectable()
export class MyProviderService {

  constructor(private nav: NavController){
  }
}

У меня была такая ошибка...
После удаления этой инъекции (и рефакторинга кода) она работала нормально.