2016-11-29 1 views
0

Ich benutze einen Datepicker und Javascript verwenden, um das Datum an die Vue-Instanz zu übergeben, aber nach dem ersten Mal rendern die Liste mit v-for, wenn ich die Funktion mit anderem Datum, es behält die vorherigen Daten auf dem Display. ist hier die Funktion i haben:Kann die v-for-Liste nicht aktualisieren, wenn Ajax die Daten

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); 
        } 
       }); 

      } 
}); 
} 
} 

jemand Idee, wie die v-for-Liste zu aktualisieren, um die neuen Spieldaten? Danke

Antwort

1

unter der Annahme, dass Ihre Daten korrekt zurückkommt, ist es wahrscheinlich nur, dass die slot nicht reaktiv ist. Versuchen:

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

bei dem obigen Code suchen Sie vermeiden sollten das Erstellen und eine neue Instanz jedes Mal, Montage Sie das Datum aktualisieren möchten. Ich bin mir nicht sicher, was Vue in diesem Szenario tun würde, aber es kann nur fehlschlagen, da Sie keine andere Instanz zu einer vorhandenen Instanz hinzufügen können.

Verschieben Sie stattdessen Ihren gesamten Vue-Code außerhalb der updateDate-Funktion.

Dann, wenn Sie die v-für von Brennen verhindern müssen, bis Sie die Daten haben, nur ein Datum param von dateReady hinzufügen und dies auf true, wenn Sie die Ajax-Anforderung abgeschlossen haben, dh

data: { 
    slot: {}, 
    dateReady: false, 
}, 
... 

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

dann können Sie nur v-if="dateReady" zu Ihrem v-for Element hinzufügen:

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

, wie Sie fdate auf die ajax-Request gehen jetzt anders gehandhabt wird, aber könnten Sie haben so etwas wie:

var datefieldVal = document.getElementById('date').value; 
 
var locationfieldVal = document.getElementById('location').value; 
 

 
if (!datefieldVal || !locationfieldVal) 
 

 
\t 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()

Im Wesentlichen Sie mehr von der Logik in Vues Instanz bewegen, dh getDate() wenn das nicht möglich ist, dann können Sie eine param einrichten, um das Datum halten Sie abrufen möchten, verwenden Sie, dass in der Ajax-Aufruf und erstellen Sie eine neue Methode, um es zu aktualisieren. Viele Möglichkeiten, um es aber das Hauptproblem ist, sicherzustellen, dass Sie nur eine einzige Instanz vue zu diesem #time-slots-container Elemente

+0

Hallo, GuyC, danke für deine Antwort. Ja, ich habe überprüft, dass die empfangenen Daten korrekt sind, nachdem die obige Syntax verwendet wurde, scheint auch nicht zu funktionieren, es behält die vorherigen Daten bei. Ich denke, die Slot-Daten wurden geändert, nur die render die Liste nicht reaktiv, keine Ahnung? – Winston

+0

Es tut uns leid, dass Sie gerade versuchen, die vue-Instanz jedes Mal neu zu erstellen, wenn Sie updateDate ausführen. Aktualisierte Antwort – GuyC

+0

Nachdem Vue-Code außerhalb der updateDate-Funktion verschoben wurde, wie wird der fdate-Parameter aufgerufen und an die Funktion updateDate übergeben? – Winston

0

hier gebunden haben, ist der V-für-Code:

   <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> 
0

Sie müssen data als zurück Methode, nicht nur ein Objekt, um reaktiv zu sein.

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

Sie können auch this.$http.get({}) als Versprechen benutzen, die Ihr ganzes jquery Chaos zu entfernen.

Dann können Sie einen fetten Pfeil verwenden => eine lexikalischen diese in Ihr Versprechen zu bekommen, so dass Sie müssen nicht passieren um Kontext (that)

Wenn Sie alle tun, dann sollten Sie Ihre Daten reagieren.

+0

Hallo, darryn.ten, danke für deine Antwort y, ich bin ein Anfänger der Verwendung von vue.js, können Sie mehr erklären, wie Sie => verwenden, um die Daten zu reaktivieren, danke ~ – Winston

+0

Sie müssen dies hier nicht wirklich tun, da Sie das Datenattribut Ihres verwenden root-Instanz, wenn es eine Komponente wäre, wäre das obige korrekt. – GuyC

+0

können Sie darüber lesen [hier] (https://babeljs.io/docs/learn-es2015/#arrows-and-lexical-this) –

Verwandte Themen