当 ajax 更新数据时无法更新 v-for 列表



i使用datepicker并使用javaScript将日期传递给VUE实例,但是在第一次使用v-for渲染列表之后,当我用其他日期调用该函数时,保留前一个数据。这是我拥有的功能:

function updateDate(fdate) {
var datefieldVal = document.getElementById('date').value;
var locationfieldVal = document.getElementById('location').value;
if (datefieldVal && locationfieldVal) {
   var tslot = new Vue({
        el: '#time-slots-container',
        data: {
            slot: {}
        },
        mounted: function () {
            this.fetchTimeslot();
        },
        methods: {
            fetchTimeslot: function () {
                var that = this;
                $.ajax({
                    type: "GET",
                    url: timeslotApiURL + "?date='" +fdate+ "'",
                    contentType: "application/json;",
                    dataType: "json",
                    success: function (data) {
                        that.slot = JSON.parse(data.d);

                        setTimeout(showTimeSlotAndButton, 500);
                    }
                });
            }
});
}
} 

有人有想法,如何使用新的插槽数据更新V-For列表?谢谢

假设您的数据正确返回,则可能只是slot没有反应性。尝试:

success: function (data) {
  Vue.set(that.$data, 'slot', JSON.parse(data.d))
  ...

查看上述代码,您应该避免每次要更新日期时创建和安装新实例。我不确定VUE在这种情况下会做什么,但它可能会失败,因为您无法将另一个实例安装到现有实例上。

而是将所有VUE代码移到更新函数之外。

然后,如果您需要防止V-FOR启动直到获得数据,只需添加dateReady的数据参数,然后在完成AJAX请求时将其设置为True,即。

data: {
  slot: {},
  dateReady: false,
},
...
success: function (data) {
  Vue.set(that.$data, 'slot', JSON.parse(data.d))
  that.dateReady = true
  ...

然后,您可以将v-if="dateReady"添加到您的v-for元素:

<div v-if="dateReady" class="time-slot-row" v-for="hourly in slot.TimeSlot">

现在如何将fdate传递给AJAX请求的方式有所不同,但是您可以拥有类似的内容:

var datefieldVal = document.getElementById('date').value;
var locationfieldVal = document.getElementById('location').value;
if (!datefieldVal || !locationfieldVal)
	return
    
var tslot = new Vue({
    el: '#time-slots-container',
    data: {
        slot: {},
        dateReady: false,
    },
    mounted: function() {
        this.fetchTimeslot();
    },
    methods: {
        fetchTimeslot: function() {
            var that = this;
            $.ajax({
                type: "GET",
                url: timeslotApiURL + "?date='" + that.getDate() + "'",
                contentType: "application/json;",
                dataType: "json",
                success: function(data) {
                    that.slot = JSON.parse(data.d);
                    that.dateReady = true
                    setTimeout(showTimeSlotAndButton, 500);
                }
            });
        },
        getDate () {
            // whatever you do here
            return ''
        },
    },
})
// wherever else you are using this...
tslot.fetchTimeslot()

本质上,您将更多的逻辑移动到VUE的实例中,即getDate()如果不可能,则可以设置一个参数以保持要获取的日期,在Ajax呼叫中使用该参数,并创建一个新方法更新它。围绕它的许多方法,但主要问题是确保您只有一个vue的实例绑定到该 #time-slots-container元素

这是v-for代码:

                <div class="time-slots-list-container">
                <p class="description"><%=GetGlobalResourceObject("OPTBSRES","SelectedStartTime") %> <span v-if="slot.SelectedSlot==null"><%=GetGlobalResourceObject("OPTBSRES","ToBeSelect") %></span><span v-if="slot.SelectedSlot!=null">{{slot.SelectedSlot}}</span> <%=GetGlobalResourceObject("OPTBSRES","ExamTimeReminderMsg") %></p>
                  <div class="time-slot-row" v-for="hourly in slot.TimeSlot">
                      <div class="hourly-indicator"><span class="time">{{hourly.Hour}}</span></div>
                      <ul class="time-slots-list">
                            <li v-for="timeslot in hourly.Slots" class="time-slot" v-bind:class="{'selected': timeslot.Status=='selected', 'unavailable': timeslot.Status =='unavailable', 'active': timeslot.Status=='available'}" v-on:click="updateSelectedSlot(hourly,timeslot), timeslot.Status='selected'">
                              <span class="time">{{timeslot.Time}}</span>
                              <div class="selected-indicator"><span aria-hidden="true" class=" fa fa-check-circle" aria-hidden="true"></span></div>
                            </li>
                      </ul>
                  </div>
            </div>

您需要返回data作为方法,而不仅仅是一个对象,以使其具有反应性。

var tslot = new Vue({
  el: '#time-slots-container',
  data() {
    return {
      slot: {}
    }
  },
  // etc

您也可以将this.$http.get({})用作承诺,它将消除整个jQuery混乱。

然后,您可以使用Fat Arrow =>将其递送到您的诺言中,因此您不必通过上下文(that

如果您执行所有操作,那么您的数据应该是反应性的。

最新更新