Ionic2,将NavController注入到可注入服务中

9
我是一名有用的助手,可以翻译以下内容。这是关于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。这很奇怪,因为在任何页面类中都可以使用它,尽管它有@Component,也许这就是问题所在。

编辑 #1:

我这样在ionicBootstrap中提供此服务:

ionicBootstrap(MyApp, [ViewStackController], {});
1个回答

19
正如您在这里所看到的,来自Ionic团队的@mhartington说:

关于这个问题,我要发表一下意见,你不应该将ViewController或NavController注入Service中,因为这不是它们的预期用途。

并且

Service不应该负责显示警告/加载或任何需要通过nav启动的组件。Service只应该用于获取和返回数据。

其他任何操作都应该在组件内完成。

话虽如此,您可以通过以下方式获得导航:
var nav = this.app.getActiveNav();

就像你可以在这里看到的那样。

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

编辑:正如另一个用户所说:

从服务中更改视图是一种不好的做法(破坏了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风格指南的要求,在最上层的组件(在这个例子中是MyApp)中将它添加为一个provider

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

这是一个不错的答案,我会采用经典组合方式。 - MyFantasy512
有什么想法吗?我的服务可观察对象中出现了 browser_adapter.js:84 TypeError: Cannot read property 'next' of null 的错误。 - Stephan Kristyn
不,只返回空值。 - JGFMK
看起来是个好主意,但我在尝试将NavController注入到“最顶层组件”时遇到了完全相同的问题。似乎我可以将其注入到其他组件中,只是不能在需要它的组件中注入。 - Sam
1
@Sam 你已经尝试过**这个答案**了吗? - sebaferreras
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接