Angular 4中Firebase Firestore数据无法存入类变量问题求助
解决Firestore获取数据后无法赋值给组件全局变量的问题
你遇到的这个报错核心原因很明确:回调函数里的this指向不对!
在你用function(doc) {...}这种普通函数作为then的回调时,函数内部的this已经不再指向你的Angular组件实例了,而是指向这个回调函数自身,所以自然找不到thisaddress这个全局变量,就抛出了Cannot set property 'thisaddress' of undefined的错误。
给你三种实用的解决方法,按推荐程度排序:
方法一:使用箭头函数(最推荐,Angular开发的标准写法)
箭头函数不会创建自己的this上下文,它会直接继承外层作用域的this(也就是你的组件实例)。修改后的代码如下:
this.newvisitordb = AddressserviceService.getdb(); var docRef = this.newvisitordb.collection("addresses").doc(this.id); docRef.get().then((doc) => { // 把普通function改成箭头函数 if (doc.exists) { console.log("Document data:", doc.data()); this.thisaddress = doc.data(); // 现在this正确指向组件,赋值成功 } }).catch((error) => { // catch回调也建议改成箭头函数,避免后续踩同样的坑 console.log("Error getting document:", error); });
方法二:提前保存组件的this到变量
如果习惯用普通函数,可以在回调外面先把组件的this存到一个变量里,比如that或者self,然后在回调里用这个变量代替this:
this.newvisitordb = AddressserviceService.getdb(); var docRef = this.newvisitordb.collection("addresses").doc(this.id); const that = this; // 先把组件的this存起来 docRef.get().then(function(doc) { if (doc.exists) { console.log("Document data:", doc.data()); that.thisaddress = doc.data(); // 用that代替this,指向组件实例 } }).catch(function(error) { console.log("Error getting document:", error); });
方法三:用async/await让异步代码更直观
把ngOnInit改成异步函数,用await等待Firestore的请求结果,这样代码逻辑更像同步代码,也能避免this指向问题:
async ngOnInit() { this.data = new AddressserviceService(); this.sub = this.route.params.subscribe(params => { this.id = params['id']; }); this.newvisitordb = AddressserviceService.getdb(); var docRef = this.newvisitordb.collection("addresses").doc(this.id); try { const doc = await docRef.get(); if (doc.exists) { console.log("Document data:", doc.data()); this.thisaddress = doc.data(); } } catch (error) { console.log("Error getting document:", error); } }
最后提个小提醒:如果后续在UI中渲染thisaddress的数据时遇到不更新的情况,可以检查下Angular的变更检测,比如用Object.assign({}, doc.data())把数据转成新对象再赋值,确保变更检测能触发。
内容的提问来源于stack exchange,提问作者vishnu vigneshwar
相关产品推荐
相关产品推荐

