我有一个时间跟踪表网络应用程序,其中每一行代表数据库中的一个用户,每一列都有一个输入字段,用户将在其中输入该特定日期的工作小时数。 一个 fiddle 向您展示它的样子:https://jsfiddle.net/L5u1fc0a/138/
基本上,我如何确保只将新数据发送到数据库。我希望(显然)在表中显示当前值,并且我正在获取该数据并将其存储在 Vue v-model
中(请参阅 fiddle 中的 worklogs
) - worklogs
中的数据是填充表的内容。我的问题是我不知道如何处理额外的时间。如果用户在特定日期再添加一小时并点击“更新”(在 fiddle 中“保存”),它将发送整个 worklogs
数据值,其中包含所有当前值 + 新值,因此如果有人只添加一个输入,它仍然会发送 worklogs
对象中的所有内容。在 fiddle 中,如果您在某处输入新值并点击“保存”按钮,您可以看到我的数组 updateData
也填充了所有现有值 - 我如何才能仅将新更新的值发送到数据库?
最佳答案
如果您随时更改数据,您将无法真正弄清楚更新了什么。您需要在工作时将它们分开,然后只保存 updateData。所以我把你的名字改成了worklogs
至saved
,并制作updateData
一个对象,将保存与 saved
类型完全相同的条目确实如此。
我做了一个合并 saved
的计算和updateData
,并将其用于边界 value
。你不能真正使用v-model
在这里,因为您无法将单个元素写回到计算字典中。但你不需要。更改时,您更新 updateData
和 value
保持一致。
(旁注:如果您将每个输入设为一个组件,则可以使用 v-model
,但仍然需要在父级中处理所有管道。)
save
函数执行后端调用它执行的任何操作,更新 saved
,并清空updateData
.
/* app instance */
new Vue({
el: '#app',
data() {
const currentDate = new Date();
return {
saved: {
"1,2018-11-01": "8",
"1,2018-11-02": "8",
"2,2018-11-03": "10",
"2,2018-11-04": "10"
},
updateData: {},
users: [
{id: 1, firstName: 'Jay', lastName: 'Carter', email: 'jayz@rocafella.com'},
{id: 2, firstName: 'Day', lastName: 'Darter', email: 'dayz@rocafella.com'}
],
secondHalf: false,
selectedYear: currentDate.getFullYear(),
selectedMonth: currentDate.getMonth() + 1,
};
},
methods: {
prevPeriod() {
if (!this.secondHalf) {
this.selectedMonth -= 1;
this.secondHalf = !this.secondHalf;
} else {
this.secondHalf = !this.secondHalf;
}
if (this.selectedMonth < 1) {
this.selectedYear -= 1;
this.selectedMonth = 12;
}
},
nextPeriod() {
if (this.secondHalf) {
this.selectedMonth += 1;
this.secondHalf = !this.secondHalf;
} else {
this.secondHalf = !this.secondHalf;
}
if (this.selectedMonth > 12) {
this.selectYear += 1;
this.selectedMonth = 1;
}
},
getMonth(date) {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
return months[date.getMonth()];
},
getWeekDay(date) {
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
return days[date.getDay()];
},
setUpdateData(userId, day, event) {
const key = this.dataKey(userId, day);
const value = event.target.value;
if (this.saved[key] !== value) {
this.$set(this.updateData, key, value);
} else {
this.$delete(this.updateData, key);
}
},
save() {
// Presumably, this would go somewhere that would refresh saved, but
// the ultimate effect is just to copy the updateData into saved and
// empty updateData
Object.assign(this.saved, this.updateData);
this.updateData = {};
},
dataKey(userId, day) {
return `${userId},${this.convertDateString(day)}`;
},
convertDateString(date) {
let isoWithTimezone = new Date(
date.getTime() - date.getTimezoneOffset() * 60000
).toISOString();
return isoWithTimezone.split("T")[0];
}
},
computed: {
allData() {
return Object.assign({}, this.saved, this.updateData);
},
getDates() {
const year = this.selectedYear;
const month = this.selectedMonth;
let currentDate = new Date(year, month - 1, 1);
const dates = [];
while (currentDate.getMonth() == month - 1) {
dates.push(currentDate);
currentDate = new Date(
currentDate.getFullYear(),
currentDate.getMonth(),
currentDate.getDate() + 1
);
}
if (this.secondHalf) {
return dates.slice(15);
} else {
return dates.slice(0, 15);
}
},
}
})
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
-moz-appearance: none;
margin: 0;
}
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div>
<p>{{this.selectedYear}} - {{this.selectedMonth}}</p>
<div>
<button @click="prevPeriod"> ‹‹ </button>
<button @click="nextPeriod"> ›› </button>
</div>
<div>
<table id="conTab">
<tr>
<td></td>
<td v-for="(date, key) in getDates" :key="key" style="font-size: 80%;"> {{getWeekDay(date)}}</td>
</tr>
<tr>
<td style="border-top-width: 0px; border-left-width: 0px"></td>
<td v-for="(date, key) in getDates" :key="key" style="font-size: 80%;"> {{getMonth(date)}} {{date.getDate()}}</td>
</tr>
<tbody>
<tr v-for="(user, i) in users" :key="user.id">
<td>
{{user.firstName}}
</td>
<td v-for="(day, key) in getDates" :key="key">
<input type="number" style="width: 35px;" :value="allData[dataKey(user.id, day)]" @change="setUpdateData(user.id, day, $event)">
</td>
</tr>
</tbody>
</table>
</div>
<div><button @click="save">SAVE</button></div>
</div>
<pre>{{$data}}</pre>
</div>
关于javascript - 将数据从表更新到数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53558239/