Ionic 2:例外:没有 NavController 的提供者

Posted

技术标签:

【中文标题】Ionic 2:例外:没有 NavController 的提供者【英文标题】:Ionic 2: EXCEPTION: No provider for NavController 【发布时间】:2016-11-02 11:33:29 【问题描述】:

我的 ionic 2/angular 2 应用有问题。

我得到了一个 app.ts,其中的“auth”部分是 implementationet。

代码如下所示:

 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 注入到 Root 组件中

所以,基本上你可以not 做如下的事情:-

constructor(private nav: NavController)

这就是注入 NavController 的方法

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

这就是 Ionic 文档要说的。

如果您想从根应用程序组件控制导航怎么办?您不能注入 NavController,因为作为导航控制器的任何组件都是根组件的子组件,因此它们不能被注入。

通过给 ion-nav 添加一个引用变量,你可以使用@ViewChild 来获取 Nav 组件的一个实例,它是一个导航控制器(它扩展了 NavController)

【讨论】:

【参考方案2】:

您不能在 根组件 中注入 NavController,因此您应该将其从代码的那部分中删除。更多信息请访问 here

请确保您的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】:

建议您在 Ionic 3+ 中使用 this.app.getActiveNavs(),因为 getActiveNav() 将在下一个主要版本中删除,因此您的函数可以编写为:

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

要推送导航堆栈,您只需导入页面(比如YourPage)然后:

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

Ionic 2 的旧行为,在 Ionic 3 中已弃用:

你可以在 Ionic 2(和 Ionic 3)中使用this.getActiveNav(),所以你的函数可以写成:

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

无论使用哪种方法,您都不需要任何importprivate 变量即可使其工作。如果您在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);
    

【讨论】:

虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。 感谢@Adam,我在两个问题上重复发布,所以你是对的,在这里不是很有帮助!我正在编辑它。【参考方案4】:

好的,我只是使用导航而不是 NavigationController,现在它可以工作了。

【讨论】:

【参考方案5】:

我用:

import  App, NavController  from 'ionic-angular';

constructor(protected app: App) 
... 

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

答案取自这里:github issues

【讨论】:

【参考方案6】:

您的导航命名错误;

this.nav.setRoot(page.component);

应该是

this.navCtrl.setRoot(page.component);

并仔细检查您的导入是否正确

import  NavController from 'ionic-angular';

【讨论】:

这不是错误! NavController 已正确导入。问题是它不能在这里注入。他通过写@ViewChild(Nav) nav: Nav; 引用了navNav 扩展了 NavController,因此可以使用它。【参考方案7】:

此错误的一个原因是当您尝试将 NavController 注入提供程序类时。 像这样:

@Injectable()
export class MyProviderService 

  constructor(private nav: NavController)
  

我刚刚遇到了那个错误... 移除此注入(并重构代码)后,它运行良好。

【讨论】:

以上是关于Ionic 2:例外:没有 NavController 的提供者的主要内容,如果未能解决你的问题,请参考以下文章

没有苹果电脑打包iOS平台的 Ionic 2程序——《Ionic 2 实例开发》更新内容

Ionic 2禁用没有导航栏的向后滑动

Ionic 2 fileTransfer.download 在 iOS 上没有反应

Ionic 2 - 如果没有互联网 + 有效表单,我如何禁用按钮

ionic 2 没有“访问控制允许来源”标头

Ionic 2.0.0-beta.24 如何在没有 ionic.config.js 的情况下导入 node_module css 文件