我有一个对象数组items
:
data() {
return {
items: [
{
id: 101,
firstName: 'Mohammed',
lastName: 'Chang',
dob: '1995-03-21'
},
{
id: 102,
firstName: 'John',
lastName: 'Smith',
dob: '1989-10-11'
},
{
id: 103,
firstName: 'Lulu',
lastName: 'Lemon',
dob: '1945-01-29'
},
]
}
},
如果我使用常规手表,并尝试比较项目,因为这些项目是对象,它们将引用同一事物,因此它们将始终返回不变:
watch: {
items: {
handler: function(revised, original) {
for (let i = 0; i < revised.length; i++) {
// check each item in revised to see if it's changed from original
if (this.isChanged(original, revised[i])) {
axios.put(URL + '/' + revised[i].id, revised[i]);
}
}
},
deep: true
}
},
methods: {
isChanged(original, item) {
// this function won't work because item is an object
// which will be referenced in original, so it will always
// be a match, i.e. not changed
for (let i = 0; i < revised.length; i++) {
// found a matching ID in the original
if (original[i].id === revised.id) {
// compare the item against the original and return
// true for changed and false for not changed
return JSON.stringify(original[i]) !== JSON.stringify(item);
}
// no match? assume true
return true;
}
}
}
}
如果我使用这样的手表,直接引用每个项目,那么它将起作用:
watch: {
'items.0': {
handler: function(revised) {
axios.put(URL + '/' + revised.id, revised);
},
deep: true
},
'items.1': {
handler: function(revised) {
axios.put(URL + '/' + revised.id, revised);
},
deep: true
},
'items.2': {
handler: function(revised) {
axios.put(URL + '/' + revised.id, revised);
},
deep: true
}
},
但是这种方法不是很实用。如果我将项目动态添加到数组怎么办?它没有观察者。
是否可以使用通配符或正则表达式来进行类似items.#
的监视?
由于无法比较原始对象,大多数开发人员是否仅使用其自己的PUT调用来更新整个数组中的每个元素?这似乎很浪费,尤其是在处理许多非常大的对象时。
watch: {
items: {
handler: function(revised) {
// no way to know which item is changed, so just
// update each item - wasteful, I know
for (let i = 0; i < revised.length; i++) {
axios.put(URL + '/' + revised[i].id, revised[i]);
}
},
deep: true
}
},
答案 0 :(得分:2)
如果我使用常规手表,并尝试比较项目,因为这些项目是对象,它们将引用同一事物,因此它们将始终返回不变:
是的,在这种情况下,您将无法在处理程序中使用以前的值,而只能使用新的值。
如果我使用这样的手表,直接引用每个项目,那么它将起作用:
是的,它将。因为您不再看嵌套的对象。
但是这种方法不是很实用。如果我将项目动态添加到数组怎么办?它没有观察者。
对,它不会有观察者。
有没有办法像上面的项目一样进行监视。#,但使用通配符或正则表达式?
不,没有类似的东西。
由于无法比较原始对象,大多数开发人员是否仅使用其自己的PUT调用来更新整个数组中的每个元素?这似乎很浪费,尤其是在处理许多非常大的对象时。
我迷路了...为什么有人应该更新整个数组中的每个元素?您所说的“自己的PUT呼叫”是什么意思?您可以编辑问题并通过该PUT调用给我一些代码示例吗?你能告诉我你想做什么吗?要实现?
编辑
现在我明白了……首先:每个应用程序应该只有一个事实要点。在您的情况下,它是外部数据库,而不是SPA本身。 SPA只是可视化该数据。因此,可以(不仅)解决问题的核心:
从后端获取真实数据。例如,在创建应用程序期间:
new Vue({
el: '#app',
data: {
items: []
},
created () {
this.$axios
.get('mountpoint')
.then(({ data }) => {
this.items = data
})
}
}
然后不要直接更改它们。例如,像这样:
新Vue({ el:“#app”,
data: {
items: []
},
created () {
this.$axios
.get('mountpoint')
.then(({ data }) => {
this.items = data
})
// Bad
setTimeout(() => {
this.items[1].firstName = 'Jan'
}, 2000)
}
}
但是这样:
新Vue({ el:“#app”,
data: {
items: []
},
methods: {
updateItems (idx, obj) {
this.item[idx] = { ...this.items[idx], ...obj }
}
},
created () {
this.$axios
.get('mountpoint')
.then(({ data }) => {
this.items = data
})
// Good, through some kind of setter
setTimeout(() => {
updateItems(1, { firstName': 'Jan' })
}, 2000)
}
}
这有什么用?现在,在进行任何更改之前,您可以在该设置器中开始测试与现有值不同的新值。而且不仅如此。如果您检测到某些更改,仍然不要更改items数组。将此更改首先与axios一起发布到后端,并且仅在后端响应更改成功后才更改项目。