【问题标题】:VueJS v-bind property not updated immediately after AJAXVueJS v-bind 属性在 AJAX 之后没有立即更新
【发布时间】:2021-04-23 16:07:20
【问题描述】:

我有一个表格,其中每一行对应一个事件。每个事件都有一组呈现为 span 元素的时间段,并且每个时间段仅在其 stopsales 属性为 true 时才被分配 na 类(使用 v-bind)

时隙是从 ajax 请求 (loadData) 中异步获取的。

我首先调用 loadData 来呈现我的时间段。我还使用 2 个按钮来调用下面的函数来更改其中一些的 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>

现在奇怪的部分来了。如果 selectedEvents包含 1 个事件, 当我调用 toggle 函数时,na 类会立即照常应用于 span 元素。

但是,如果selectedEvents 包含2个事件,当我调用toggle函数时,na类是立即仅应用于其父是最后选择的事件的跨度元素。 na 类尚未分配给作为第一个事件的子级的 span 元素。但是如果我在表中执行任何其他甚至不涉及这 2 个函数的操作,例如打开一个模式,na 类也适用于这些元素。

这是一些 VueJS 计时问题,其中 DOM 仅在触发 JS 事件后更新?是否有等待在下一个事件触发器上部署的更改队列?

【问题讨论】:

  • 不,Vue 不等待任何 JS 事件。似乎更像是您这边的反应性问题。你的data() 函数到底长什么样?
  • 我不确定您对 data() 函数的含义。 loadData() 负责从我的后端获取数据。如果您的意思是后端功能,那么它有多重要?根据console.log() 提取的数据是正确的
  • 啊,我明白了。我用更多代码和更具体的问题描述更新了我的问题。请检查一下。
  • @ThatGuy 你的数据看起来也有问题 - 它应该返回一个对象并设置如下:data() { return { events: [ { id: 1, name: 'event'}]}}

标签: javascript html ajax vue.js axios


【解决方案1】:

您的addToToggleCheck 似乎有问题。使用索引器设置数组值不是响应式的(Vue 无法检测到更改 - 适用于 Vue 2.x)。

this.toggleCheck[timeslotId] = true/false; 替换为Vue.set(this.toggleCheck, timeslotId, true/false);

了解Change Detection Caveats for Arrays

如果您的代码确实与您的问题完全相同,类似的问题出现在 event.timeslot = response_item.timeslot; 行上的 loadData 方法中,您正在向事件对象添加新属性

阅读Change Detection Caveats for Objects

要么使用Vue.set(event, 'timeslot', response_item.timeslot),要么在数据中引入属性:

data() {
  return {
      events: [
        { 
          id: 1, 
          name: "Event 1",
          timeslot: {}
        },
        { 
          id: 2, 
          name: "Event 2",                  
          timeslot: {}
        }
      ],
      selectedEvents: [],
      toggleCheck: []
  }
}

【讨论】:

  • Vue.set(event, 'timeslot', response_item.timeslot) 解决了我的问题!谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多