Ionic 3. 没有 NavController 的提供者

Ionic 3. No provider for NavController

我的问题与找到的问题相似 here

但我不确定他的情况是否相同,因为有时当我停止应用程序并使用 ionic serve 重新启动时错误会消失。错误returns 再次随机返回。我注意到,当我在 app.component.ts 构造函数中使用调试器语句时,我可以绕过错误。任何帮助,将不胜感激。谢谢。

这是我的代码

app.component.ts

export class MyApp {
    @ViewChild('content') nav: Nav;

    rootPage: any = HomePage;

    pages: Array<{ title: string, component: any }>;


    constructor(public platform: Platform,
    public statusBar: StatusBar,
    public splashScreen: SplashScreen) {
    this.initializeApp();

    this.pages = [
      { title: 'Dashboard', component: DashboardPage },
    ];
    debugger
  }

  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.
      this.statusBar.styleDefault();
      this.splashScreen.hide();
    });
  }

  openPage(page) {
    // Reset the content nav to have just this page
    // we wouldn't want the back button to show in this scenario
    this.nav.setRoot(page.component);
  }
}

app.html

<ion-menu [content]="content">
  <ion-header>
    <ion-toolbar>
      <ion-title>Menu</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-content>
    <ion-list>
      <button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
        {{p.title}}
      </button>
    </ion-list>
  </ion-content>

</ion-menu>
<ion-nav #content swipeBackEnabled="false" [root]="rootPage"></ion-nav>

home.ts

export class HomePage {
  token: string;
  constructor(public navCtrl: NavController,
    public menuCtrl: MenuController,
    public storage: Storage) {
    setTimeout(() => {
      this.storage.get('_token').then((token) => {
        this.token = token;
        if (this.token && this.token.length > 0) {
          this.navCtrl.setRoot(DashboardPage)
        } else {
          this.navCtrl.setRoot(LoginPage)
        }
      }).catch((error) => {
        console.log(error);
        this.navCtrl.setRoot(LoginPage)
      });
    }, 1000)
  }

  ionViewWillEnter() {
    this.menuCtrl.enable(false);
  }
  ionViewWillLeave() {
    this.menuCtrl.enable(true);
  }

}

login.ts

export class LoginPage {
  username: string;
  password: string;

  constructor(public navCtrl: NavController,
    public navParams: NavParams,
    public userProvider: UserProvider,
    public storage: Storage,
    public alertCtrl: AlertController,
    public menuCtrl: MenuController) {

  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LoginPage');
  }

  login() {
    console.log("Logging in...", this.username, this.password);
    var credentials = { 'email': this.username, 'password': this.password };
    this.userProvider.login(credentials).then((validResponse: any) => {
      console.log('success', validResponse);
      var data = validResponse.data;
      this.storage.set('_token', data.token);
      this.navCtrl.setRoot(DashboardPage);
    }).catch((errorResponse: any) => {
      console.log('error', errorResponse);
      var title = '';
      var subTitle = '';
      title = "Oops!"
      if (errorResponse.status == 401) {
        subTitle = "Invalid Username/Password";
      } else {
        var errorObject = errorResponse.error;
        if (errorObject.errors) {
          for (let error of errorObject.errors) {
            subTitle += error + '. ';
          }
        } else {
          subTitle = errorResponse.message;
        }
      }
      this.presentAlert(title, subTitle);
    });
  }

  presentAlert(title, subTitle) {
    let alert = this.alertCtrl.create({
      title: title,
      subTitle: subTitle,
      buttons: ['Ok']
    });
    alert.present();
  }

  ionViewWillEnter() {
    this.menuCtrl.enable(false);
  }
  ionViewWillLeave() {
    this.menuCtrl.enable(true);
  }

}

login.html

<ion-content padding>
  <div class="login-holder">
    <ion-img class="logo" width="120" src="../../assets/imgs/logo.png"></ion-img>
    <br>
    <ion-img class="hero" width="250" src="../../assets/imgs/restaurant.png"></ion-img>
    <ion-input class="username" [(ngModel)]="username" type="text" placeholder="Phone or Email"></ion-input>
    <ion-input class="password" [(ngModel)]="password" type="password" placeholder="Password"></ion-input>
    <button class="login" ion-button full (click)="login()">Login</button>
  </div>
</ion-content>

我的流程是这样的,HomePage是进入登录页面之前的临时屏幕, 超时后,我转到登录页面或仪表板页面,具体取决于它们是否已经在本地存储中拥有令牌。从登录页面,我将用户带到仪表板页面。

由于我是 angular 和 ionic 的新手,所以我什至不确定自己是否做对了。我已经研究了堆栈溢出中的所有类似问题。

再次感谢您的宝贵时间。

将您的 Home.ts 更改为:

export class HomePage {
  token: string;
  constructor(public navCtrl: NavController,
    public menuCtrl: MenuController,
    public storage: Storage) {

  }

  ionViewWillEnter() {
    this.menuCtrl.enable(false);
  }
  ionViewWillLeave() {
    this.menuCtrl.enable(true);
  }

  ionViewDidLoad() {
    setTimeout(() => {
      this.storage.get('_token').then((token) => {
        this.token = token;
        if (this.token && this.token.length > 0) {
          this.navCtrl.setRoot(DashboardPage)
        } else {
          this.navCtrl.setRoot(LoginPage)
        }
      }).catch((error) => {
        console.log(error);
        this.navCtrl.setRoot(LoginPage)
      });
    }, 1000)
  }

}

看了一会儿。我发现了问题。我的 home.ts 中缺少 @IonicPage 装饰器。添加后解决。