我们跳进了Vue,完全喜欢商店的想法,将页面状态与演示文稿分开。我们编写了一个zippy alert组件,它显示store.pageError中的任何警告字符串。
然后我们想添加confirm(),所以我们为组件提供了一个ref,以及一个返回promise的popConfirm()方法,每当我们想要确认某些内容时,我们都会调用...
vm.$refs.alertConfirm.confirm("Are you sure?")
.then(function(conf){if(conf) /* do it */ })
......并且该组件负责管理自己的可见性,而不会在商店中发生任何事情。
这非常有效,很快很多组件都开始萌芽,因此可以直接调用它们作为方法。在最新的版本中,我们实现了一个包含六个步骤的隧道,其中api调用和用户操作与Promise.all()并行调用,并且它工作得很好,但是商店已经退了一大步,越来越多的状态是直接在Vue组件中管理。这些组件不再是商店状态的愚蠢表示,而是内部管理状态的功能序列越来越少。
我们如何重新确定商店的想法,同时保持将这些短函数序列称为方法的便利性?
这是我们的隧道代码。这当前存在于Vue组件的methods
中,其中标记,状态和顺序逻辑被欢乐地混合在一起。 这可能不错?
startTunnel(idNote) {
var rslt = {
idNote: idNote,
photoJustif: null,
date: null,
currency: "",
montant: null
}
//---------------Step 1: photo et count notes in parallel
Promise.all([
me.$refs.camera.click(),
getUrlAsJson("api/note/getNotes"),
])
//---------------Step 2: Choose note if > 1
.then(function (results) {
rslt.photoJustif = results[0];
me.$refs.loader.hide();
// if we already know the note, go straight to Step 3.
if (rslt.idNote)
return true;
// if no idNote supplied, and only one returned from server, assign it.
if (results[1].notes.length === 1 && !rslt.idNote) {
rslt.idNote = results[1].notes[0].idNote;
return true;
}
else {
return me.$refs.chooseNote.choose(results[1].notes)
// combine photoJustif from Step 1 with idNote chosen just above.
.then(function (idNoteChosen) { rslt.idNote = idNoteChosen; return true })
}
})
//--------------Step 3: OCR
.then(() => me.doOcr(rslt))
//--------------Step 4: Choose nature and retrieve card statement from server in parallel
.then(function (ocrResult) {
me.$refs.loader.hide()
if (ocrResult != null) { //Si ocr n'a pas échoué
rslt.date = ocrResult.date;
rslt.montant = ocrResult.montant;
rslt.currency = ocrResult.currency;
return Promise.all([
me.$refs.chooseNature.init(rslt.idNote, ocrResult.grpNatures),
getUrlAsJson("api/expense/relevecarte/filterpers", { IdPerson: 1, montant: ocrResult.montant })
]);
}
else return null;
})
//--------------Step 5: Choose card transaction
.then(function (natureAndFraisCartes) {
if (natureAndFraisCartes != null) {
rslt.idNature = natureAndFraisCartes[0].id;
if (rslt.montant != null && natureAndFraisCartes[1].length > 1)
return me.$refs.choixFraisCarte.init(rslt, natureAndFraisCartes[1]);
else
return null;
}
else return null;
})
//------------- Step 6: End tunnel
.then(function (fraisCarte) {
me.$refs.loader.popInstant();
me.$refs.form.idNote.value = rslt.idNote;
var jsonObject;
if (fraisCarte != null) {
me.$refs.form.action.value = 15;
jsonObject = {
"DateFrais": rslt.date,
"IdNature": rslt.idNature,
"MontantTicket": rslt.montant,
"Justificatif": rslt.photoJustif,
"idCarte": fraisCarte.id
};
}
else {
me.$refs.form.action.value = 14;
jsonObject = {
"DateFrais": rslt.date,
"IdNature": rslt.idNature,
"MontantTicket": rslt.montant,
"Justificatif": rslt.photoJustif,
"idCarte": 0
};
}
me.$refs.form.obj.value = JSON.stringify(jsonObject);
me.$refs.form.submit();
})
.catch(function (error) {
me.$refs.loader.hide();
me.active = false;
me.rslt = {
idNote: idNote,
photoJustif: null,
date: null,
montant: null
};
console.log(error);
vueStore.pageError = me.allStrings.tunnelPhoto.erreurTunnel;
})
}
答案 0 :(得分:0)
看起来问题是你摆脱了声明性的思考并且开始思考。当您想要确认某些内容时,您应该设置一个temp
数据项,该组件应该以与查看警报字符串相同的方式观察它。
确认回复中应该有一个数据项,表明您是在等待回复,还是已经确认或已被取消。这是所有程序状态。
使用confirmPrompt
是代码气味。这并不总是错的,但你应该总是考虑为什么要这样做。 $refs
之类的内容建议应该通过设置me.$refs.loader.hide();
数据项来控制程序状态更改。