【发布时间】:2019-11-22 16:54:40
【问题描述】:
我不得不承认,这是我在 TypeScript-JavaScript 中看到的最奇怪的错误(我在 TypeScript 中获得了 Model 类,在 JS 中获得了 ReactJS 组件...)。我有一个 Promo 对象的列表,其中一个属性“_listCompte”是 Compte 对象的列表。
Promo 列表是通过从数据库中检索数据创建的,此时一切正常
之后我在 listPromo 上得到了一个 forEach 并且它可以工作,但是当我尝试在 listCompte 上使用 forEach 进行迭代时 好像是空的。
ReactJS 组件:
class DettesView extends Component{
state = {
loading: true,
activeItem: "DI4",
listPromo: []
};
componentDidMount() {
let listPromo = [];
FirebaseAPI.getDatabase().collection("Promo")
.onSnapshot((docSnapshot)=>{
docSnapshot.forEach((doc)=>{
const promoData = doc.data();
let promo = Promo.fromData({
nom: promoData.nom,
promoId: promoData.promoId
});
promoData.listCompte.forEach((compteRef)=>{
compteRef.get()
.then((doc)=>{
if(doc.exists){
let compte = Compte.fromData(doc.data());
promo.addCompte(compte);
}
}
)
});
listPromo.push(promo);
});
console.log("listPromo", listPromo);
this.setState({
loading: false,
status: true,
listPromo: listPromo
});
}, (error)=>{
this.setState({
loading: false,
status: false,
errorMessage: error.getMessage(),
errorCode: error.getCode()
});
});
}
toggleTabs = tab => () => {
if (this.state.activeTab !== tab) {
this.setState({
activeTab: tab
});
}
};
render() {
const {loading, listPromo} = this.state;
if(loading)
return (
<MDBContainer fluid>
<MDBRow center={true}>
<MDBCol size="2" className="mt-5">
<MDBCard>
<MDBCardBody>
<img src={gifLoading} alt="gif-loading"/>
<h1 className="mt-4 text-center">Loading...</h1>
</MDBCardBody>
</MDBCard>
</MDBCol>
</MDBRow>
</MDBContainer>
);
else if(this.state.status)
return (
<div className="classic-tabs">
<MDBNav classicTabs color="cyan">
{listPromo.map((value, index) => (
<MDBNavItem key={index}>
<MDBNavLink to="#" active={this.state.activeItem === value.nom} onClick={this.toggleTabs(value.nom)}>
{value.nom}
</MDBNavLink>
</MDBNavItem>
))}
</MDBNav>
<MDBTabContent
className="card"
activeItem={this.state.activeItem}
>
{listPromo.map((value, index) => {
console.log("value of property 'listCompte' in a 'Promo' object", value.listCompte);
console.log("size of property 'listCompte' in a 'Promo' object", value.listCompte.length);
return (
<MDBTabPane tabId={value.nom} key={index}>
<MDBTable hover>
<MDBTableHead>
<tr>
<th>Prénom</th>
<th>Nom</th>
<th>Promo</th>
<th>Dette</th>
</tr>
</MDBTableHead>
<MDBTableBody>
{value.listCompte.map((valueCompte, indexCompte) => {
console.log("compte", valueCompte);
return (
<tr key={indexCompte}>
<td>{valueCompte.nom}</td>
<td>{valueCompte.prenom}</td>
<td>{value}</td>
<td>{valueCompte.dette}</td>
</tr>
)
})}
</MDBTableBody>
</MDBTable>
</MDBTabPane>
)
})}
</MDBTabContent>
</div>
);
else
return (
<MDBContainer fluid>
<MDBRow center={true} className="mt-3">
<MDBCol size="6">
<MDBCard>
<MDBCardBody>
<img src={gifError} alt="gif-error" className="text-center img-fluid"/>
<h2>Erreur 😧 : {`${this.state.errorCode}`}</h2>
<h4>=> {`${this.state.errorMessage}`}</h4>
</MDBCardBody>
</MDBCard>
</MDBCol>
</MDBRow>
</MDBContainer>
);
}
}
(我已经尝试使用 map 而不是 forEach 但它不起作用)。如果有人有想法,谢谢
促销 TS 级:
interface PromoData {
promoId: string;
nom: string;
}
class Promo {
private _nom: string;
private _promoId: string;
private _listCompte: Array<Compte>;
constructor(proId: string, nom: string) {
this._nom = nom;
this._promoId = proId;
this._listCompte = new Array<Compte>();
}
get listCompte(): Array<Compte> {
return this._listCompte;
}
addCompte = (value: Compte) => {
this._listCompte.push(value);
};
get promoId(): string {
return this._promoId;
}
set promoId(value: string) {
this._promoId = value;
}
get nom(): string {
return this._nom;
}
set nom(value: string) {
this._nom = value;
}
static fromData(promoData: PromoData): Promo{
return new this(
promoData.promoId,
promoData.nom
);
}
logError() : void {
console.log(this._listCompte);
this._listCompte.forEach((compte: Compte)=>{
console.log(compte)
})
}
}
和 Compte TS-Class
interface CompteData {
promoId: string;
nom: string;
prenom: string;
dette: number;
isKefet: boolean;
compteId: string;
}
class Compte {
private _nom: string;
private _prenom: string;
private _dette: number;
private _promoId: string;
private _isKefet: boolean;
private _compteId: string;
constructor(compteId: string, nom: string, prenom: string, dette: number, isKefet: boolean, promoId: string) {
this._compteId = compteId;
this._nom = nom;
this._prenom = prenom;
this._dette = dette;
this._promoId = promoId;
this._isKefet = isKefet;
}
get compteId(): string {
return this._compteId;
}
set compteId(value: string) {
this._compteId = value;
}
get nom(): string {
return this._nom;
}
set nom(value: string) {
this._nom = value;
}
get prenom(): string {
return this._prenom;
}
set prenom(value: string) {
this._prenom = value;
}
get dette(): number {
return this._dette;
}
set dette(value: number) {
this._dette = value;
}
get isKefet(): boolean {
return this._isKefet;
}
set isKefet(value: boolean) {
this._isKefet = value;
}
static fromData(compteData: CompteData): Compte{
return new this(
compteData.compteId,
compteData.nom,
compteData.prenom,
compteData.dette,
compteData.isKefet,
compteData.promoId,
)
}
}
(我所有的属性都有 getter 和 setter)
------- 附加测试-------
通过在渲染中添加 listPromo 的 console.log
【问题讨论】:
-
您需要在调用
addCompte的位置显示代码并使用forEach。由于您正在从数据库中获取数据,因此这可能是一个异步问题。 -
尝试将数组 _listCompte 初始化为 [] 而不是使用类构造函数
-
我使用 Firebase 作为 Cloud Firestore 数据库,它是 Promise “面向”的
-
@voiys 我已经尝试过了,但它什么也没解决:'(
标签: javascript reactjs typescript