Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
689 views
in Technique[技术] by (71.8m points)

angular - Ionic2, inject NavController to Injectable Service

I have a problem with Injectable Service in Angular2 using Ionic2 framework.

My service looks like this:

import {Injectable} from '@angular/core';
import {NavController} from 'ionic-angular';

@Injectable()
export class ViewStackController {
  static get parameters() {
    return [[NavController]];
  }

  constructor(nav) {
  }
}

And I get error No provider for NavController. It's strange because in any Page class it's working, though it has @Component, maybe that's the catch.

edit #1:

I am providing this service in ionicBootstrap, like this:

ionicBootstrap(MyApp, [ViewStackController], {});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 {
  // ...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...