Ionic Provider中使用NavController报错:Cannot read property 'pop' of null
嘿,我一眼就揪出问题根源了——Provider不是Angular/Ionic的组件,它没有对应的视图模板,你用@ViewChild('myContent')去获取NavController根本行不通,这直接导致navCtrl一直是null,调用pop()的时候自然就抛出那个错误啦。
下面给你三种靠谱的解决方案,按需选择:
方案1:利用已注入的App实例获取根导航控制器
你已经在构造函数里注入了App,直接用它就能拿到根导航控制器,简单直接:
@Injectable() export class ServerResponseProvider { constructor( public http: Http, public alertCtrl: AlertController, protected injector: Injector, private app: App ) { console.log('Hello ServerResponseProvider Provider'); } httpGetRes(url) { return Observable.create(observer => { this.http.get(url).subscribe(response => { // 先获取根导航,再判断是否存在后执行pop const rootNav = this.app.getRootNav(); if (rootNav) { rootNav.pop(); } observer.next(response); }, error => { observer.error(error); }); }); } }
方案2:用Injector延迟注入NavController(Ionic 3+推荐)
如果想直接在Provider里使用NavController,得用Injector延迟注入,避免循环依赖的坑:
@Injectable() export class ServerResponseProvider { private navCtrl: NavController; constructor( public http: Http, public alertCtrl: AlertController, protected injector: Injector, private app: App ) { // 延迟注入,避开组件初始化时的循环依赖问题 setTimeout(() => { this.navCtrl = this.injector.get(NavController); }, 0); console.log('Hello ServerResponseProvider Provider'); } httpGetRes(url) { return Observable.create(observer => { this.http.get(url).subscribe(response => { if (this.navCtrl) { this.navCtrl.pop(); } observer.next(response); }, error => { observer.error(error); }); }); } }
方案3:调用Provider方法时传入NavController实例(最灵活)
如果只是在特定场景下需要导航操作,不如直接把当前组件的NavController传给Provider的方法,这样最稳妥:
组件中的调用代码
constructor( private serverResp: ServerResponseProvider, private navCtrl: NavController ) {} someTriggerFunction() { this.serverResp.httpGetRes('你的请求URL', this.navCtrl).subscribe( res => console.log('请求成功'), err => console.error('请求失败', err) ); }
Provider中的方法修改
httpGetRes(url, navCtrl: NavController) { return Observable.create(observer => { this.http.get(url).subscribe(response => { navCtrl.pop(); observer.next(response); }, error => { observer.error(error); }); }); }
最后再提醒一句:Provider是用来处理业务逻辑、数据请求这类和视图无关的功能的,别再用@ViewChild在里面搞视图相关的操作啦,这完全是用错地方哦~
内容的提问来源于stack exchange,提问作者Mohammed Abdul kadhir
相关产品推荐
相关产品推荐

