在ionic2中自定义服务:该服务需要使用到NavController

       如果在自定义的服务中的constructor中直接注入(NavControlll) private navCtrl: NavController,然后再page页面或组件中的constructor中也采用注入的方式,可能会出现这样的错误:

No provider for NavController! (YourService -> NavController)

那该如何是好呢?

简单的方法有:在page中直接传递navCtrl对象到Service或者Provider中的constructor(此时使用该服务就不能使用注入的方式)或具体方法中(作为方法的参数),然后通过该对象使用。

另一种方案呢?

既保留服务能直接在构造方法中直接注入,又能使用navController对象。

But keep in mind, this is not good practice– services should not be tied to the UI of your application.(这话需要特别注意)

参考:

Ionic 2 UI/Alert from a Angular 2 Service

Ionic 2 use NavController in Service to show Alerts

Ionic2, inject NavController to Injectable Service


Ionic 2 UI/Alert from a Angular 2 Service

When you create an Ionic 2 page/component your constructor can inject the NavController like this:

constructor(private nav:NavController) {}

However, if you have tried this from a service then you’ve probably found this error:

No provider for NavController! (YourService -> NavController)

The particular use case i was tackling is to provide a simple Alert when there is an error in my service that was using Angular 2’s http.

To fix the problem, first import IonicApp:

import {IonicApp, Alert} from 'ionic-angular';

In our constructor we inject our app:

constructor(private app: IonicApp) {}

Now to get the NavController and present some UI we can:

let alert = Alert.create({title: 'Error', message: message, buttons: ['OK']});
var nav = this.app.getActiveNav();
nav.present(alert);

Hope this helps someone out struggling with the same problem.



Ionic 2 use NavController in Service to show Alerts

June 20, 2016  Uncategorized  3 Comments  Can Kattwinkel

Usually you inject Nav:NavController into your classes constructor to use it:

But if you are working in a service you will receive the following error:

If you want to show alerts from within a service you are required to use the NavController.  To do so simply create the private field nav with type NavController. Then use the app.getActiveNav method provided by ionic-angular. See the snippet below for a full example:

Now you can show dialogs and alerts from a service in Ionic 2. But keep in mind, this is not good practice– services should not be tied to the UI of your application.



As you can se here, @mhartington (from ionic team) says:

Just to chime in on this, you shouldn't be injecting ViewController or NavController into Service. This is not their intended purpose.

And

The service shouldn't be responsible for displaying alerts/loading/ or any component that needs to be activated by nav. A service should just be for getting and returning data.

Anything else should be done within the component.

That being said, you can obtain the nav by doing

var nav = this.app.getActiveNav();

Like you can see here.

=================================================

EDIT: As another user said:

It's bad practice to change a view from a service (broken MVC). However, you could send events from services to the main controller, and the controller can use NavController (best way), or you could send NavController to your service like an attribute (not bad way...). Or you may need to create a component instead of using the service.

So, a better way to do it, would be:

First, add an observable in your service, to know when the dismiss should be called:

import {Injectable} from '@angular/core';
import {Platform} from 'ionic-angular';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class MyCustomService {

  // Observables we're going to use
  private dismissObserver: any;
  public dismiss: any;

  constructor(private platform: Platform){
    // Your stuff
    // ...

    this.dismissObserver = null;
    this.dismiss = Observable.create(observer => {
        this.dismissObserver = observer;
    });
  }

  public yourMethod(...):void {
    // Here we send the order to go back to the home page
    this.dismissObserver.next(true);
  }
}

And then only, in your app.ts (or in your top-most component):

 initializeApp(): void {
    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();

      // We subscribe to the dismiss observable of the service
      this.myCustomService.dismiss.subscribe((value) => {
        this.navController.setRoot(HomePage);
      });
    });
  }

Remember to add it in the ionicBootstrap of your app:

ionicBootstrap(MyApp, [MyCustomService, ...], {
  //statusbarPadding: true
});

Or, following the Angular2 Style Guide, add it as a provider in the top-most component (MyApp in this case):

@Component({
  templateUrl: 'build/app.html',
  directives: [...],
  providers: [MyCustomService]
})
class MyApp {
  // ...
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值