[英]VueJS v-bind property not updated immediately after AJAX
I have a table where each row corresponds to an event.我有一个表,其中每一行对应一个事件。 Each event has a set of timeslots rendered as span elements and each timeslot is assigned the na class (with v-bind) only when its stopsales property is true
每个事件都有一组呈现为跨度元素的时隙,并且每个时隙仅在其stopsales属性为 true 时被分配na class(使用 v-bind)
The timeslots are fetched asynchronously from an ajax request ( loadData ).从 ajax 请求 ( loadData ) 异步获取时隙。
I call loadData to render my timeslots initially.我最初调用loadData来渲染我的时间段。 There are also 2 buttons I use to call the function below to change the stopsales property of some of them:
我还使用 2 个按钮来调用下面的 function 来更改其中一些的 stopsales 属性:
<div v-for="event in events">
<label>
<input type="checkbox" @change="handleEvents(event); " :id="event"
:value="event" v-model="selectedEvents">
{{event.name}}
</label>
</div>
<button class="btn btn-success" v-on:click="toggle(true);">Activate</button>
<button class="btn btn-danger" v-on:click="toggle(false);">Stop</button>
<td v-for="event in selectedEvents">
<span v-for="(ev, index, key) in event.timeslot">
<span class="label label-default" v-bind:class="{ na: ev.stopsales }"></span>
<input type="checkbox" :timeslot="ev.timeslotId"
v-on:click="addToToggleCheck($event,ev.timeslotId)">
</span>
</td>
<script>
const app = new Vue({
el: '#app',
data: {
events: [
{
id: 1,
name: "Event 1",
},
{
id: 2,
name: "Event 2",
}
],
selectedEvents: [],
toggleCheck: []
},
methods: {
loadData(event) {
axios.post(url, {
event: event.id
})
.then(function (response) {
var response_item = response.data.data[0];
event.timeslot = response_item.timeslot;
});
},
handleEvents(event) {
var currentObj = this;
this.selectedEvents.forEach(function (selectedEvent) {
if (selectedEvent.id === event.id) {
currentObj.loadData(event);
}
});
},
addToToggleCheck(event, timeslotId) {
if (event.target.checked) {
this.toggleCheck[timeslotId] = true;
} else {
this.toggleCheck[timeslotId] = false;
}
},
toggle(activate){
var selectedToToggle = [];
var _this = this;
for (var key in this.toggleCheck) {
if (this.toggleCheck[key]) {
selectedToToggle.push(key);
}
}
axios.post(toggleUrl, {
evIds: selectedToToggle,
activate: activate
})
.then(function (response) {
_this.selectedEvents.forEach(function (selectedEvent) {
_this.loadData(selectedEvent);
});
}
}
}
</script>
Now here comes the weird part.现在奇怪的部分来了。 If selectedEvents only contains 1 event , when I call the toggle function, the na class is immediately applied as normal to the span elements.
如果selectedEvents仅包含 1 个事件,当我调用切换function 时, na class 会立即正常应用于跨度元素。
However, if selectedEvents contains 2 events , when I call the toggle function, the na class is immediately applied only to the span elements whose parent is the last event chosen.但是,如果selectedEvents包含 2 个事件,当我调用切换function 时, na class 会立即仅应用于其父级是最后选择的事件的跨度元素。 The na class is not yet assigned to the span elements that are children of the first event.
na class 尚未分配给作为第一个事件的子元素的 span 元素。 However if I do anything else in my table that does not even involve those 2 functions, like for example opening a modal, the na class is applied to those elements too.
但是,如果我在我的表中做任何其他甚至不涉及这两个功能的事情,例如打开一个模式,那么na class 也适用于这些元素。
Is this some VueJS timing issue where the DOM is only updated after a JS event is triggered?这是一些 VueJS 计时问题,其中 DOM 仅在触发 JS 事件后更新? Is there a queue of changes waiting to be deployed on the next event trigger?
是否有等待在下一个事件触发器上部署的更改队列?
Your addToToggleCheck
seems problematic.您的
addToToggleCheck
似乎有问题。 Setting array value using indexer is not reactive (Vue cannot detect the change - applies to Vue 2.x).使用索引器设置数组值不是被动的(Vue 无法检测到更改 - 适用于 Vue 2.x)。
Replace this.toggleCheck[timeslotId] = true/false;
替换
this.toggleCheck[timeslotId] = true/false;
with Vue.set(this.toggleCheck, timeslotId, true/false);
使用
Vue.set(this.toggleCheck, timeslotId, true/false);
Read about Change Detection Caveats for Arrays阅读有关Arrays 的更改检测注意事项
And if your code really looks exactly as in your question, similar problem is in the loadData
method on event.timeslot = response_item.timeslot;
如果你的代码看起来和你的问题完全一样,类似的问题是在
event.timeslot = response_item.timeslot;
上的loadData
方法中。 line where you are adding new property to an event object向事件添加新属性的行 object
Read about Change Detection Caveats for Objects阅读有关对象的更改检测警告
Either use Vue.set(event, 'timeslot', response_item.timeslot)
or introduce the property in data:要么使用
Vue.set(event, 'timeslot', response_item.timeslot)
要么在数据中引入属性:
data() {
return {
events: [
{
id: 1,
name: "Event 1",
timeslot: {}
},
{
id: 2,
name: "Event 2",
timeslot: {}
}
],
selectedEvents: [],
toggleCheck: []
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.