Ionic2, внедрить NavController в Injectable Service

У меня проблема с Injectable Service в Angular2 с использованием фреймворка Ionic2.

Мой сервис выглядит так:

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

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

  constructor(nav) {
  }
}

И я получаю ошибку No provider for NavController. Странно, потому что в любом классе Page он работает, хоть и имеет @Component, может в этом загвоздка.

изменить №1:

Я предоставляю эту услугу в ionicBootstrap, например:

ionicBootstrap(MyApp, [ViewStackController], {});

person MyFantasy512    schedule 15.06.2016    source источник


Ответы (1)


Как вы можете увидеть здесь, @mhartington (из команды ionic) пишет:

Просто чтобы отметить это, вы не должны внедрять ViewController или NavController в Service. Это не является их прямым предназначением.

А также

Служба не должна нести ответственность за отображение предупреждений/загрузку/или любой компонент, который необходимо активировать с помощью nav. Служба должна быть предназначена только для получения и возврата данных.

Все остальное должно быть сделано внутри компонента.

При этом вы можете получить навигацию, выполнив

var nav = this.app.getActiveNav();

Как видите, здесь.

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

EDIT: Как сказал другой пользователь:

Плохая практика - менять представление из службы (сломанный MVC). Однако вы можете отправлять события из служб на главный контроллер, и контроллер может использовать NavController (лучший способ), или вы можете отправить NavController в свою службу как атрибут (неплохой способ...). Или вам может понадобиться создать компонент вместо использования службы.

Итак, лучший способ сделать это:

Во-первых, добавьте observable в свой сервис, чтобы знать, когда следует вызывать dismiss:

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

И затем только в вашем app.ts (или в самом верхнем компоненте):

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

Не забудьте добавить его в ionicBootstrap вашего приложения:

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

Или, следуя Руководству по стилю Angular2, добавьте его как provider в самый верхний компонент. (MyApp в данном случае):

@Component({
  templateUrl: 'build/app.html',
  directives: [...],
  providers: [MyCustomService]
})
class MyApp {
  // ...
}
person sebaferreras    schedule 15.06.2016
comment
Или (в зависимости от сценария/использования службы) передать навигацию страницы в качестве параметра службе - person Will.Harris; 15.06.2016
comment
Отличный ответ, в данном случае я выбираю классическую композицию. - person MyFantasy512; 16.06.2016
comment
Ммм есть идеи что это может быть? browser_adapter.js:84 TypeError: Cannot read property 'next' of null в моем сервисе можно наблюдать. - person Steve K; 12.07.2016
comment
var nav = this.app.getActiveNav(); - это не сработало для меня - person JGFMK; 18.08.2017
comment
Жаль слышать, что @JGFMK ... может быть, это было изменено в какой-либо из последних версий Ionic? Выдает какую-нибудь ошибку? - person sebaferreras; 18.08.2017
comment
Нет - просто ничего не возвращает - person JGFMK; 18.08.2017
comment
Казалось хорошей идеей, но у меня точно такая же проблема, когда я пытаюсь внедрить NavController в самый верхний компонент. Кажется, я могу внедрить его в другие компоненты, но не в тот компонент, в котором он мне нужен. - person Sam; 23.09.2017
comment
@ Сэм, ты уже пробовал этот ответ? - person sebaferreras; 23.09.2017