2016-02-26 5 views
7

Ich mache eine einfache Reaktion native App, die mehrere Listen hat und gibt dem Benutzer die Möglichkeit, ein Element in einer dieser Listen zu aktualisieren oder neue Elemente zur Liste hinzuzufügen.Wie optimistisch zu aktualisieren Artikel in einem ListView

Wie jedoch zuvor auf StackOverflow hingewiesen wurde, kann man ein Element nicht zu einem ListView hinzufügen oder schieben, weil es eine unveränderliche Datenstruktur sein soll. dh in diesem Code kann man nicht ein neues Element in die Datenquelle schiebt

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
var data = ds.cloneWithRows(responseData) 
var obj = {}; 
obj['someproperty'] = 'foo'; 
data.push(obj); //cannot push a new item into data 

Also, was ich stattdessen getan ist, eine Kopie (this.state.items; in Code unten) der Daten, die ich vom Server holen zu halten (und der Ich rufe cloneWithRows an), an diese Kopie anhängen (oder sie aktualisieren, wenn es eine Bearbeitung ist), und dann cloneWithRows auf der mutierten Kopie aufrufen, wenn es eine Änderung gibt (entweder durch eine Bearbeitung oder Erstellung eines neuen Elements) und die ui aktualisieren, und dann den Server aktualisieren (dieser letzte Teil außerhalb des Bereichs der reaktiven nativen App). Also zusammenfassend habe ich eine Kopie der Daten, die ich mutieren kann, um eine Datenquelle für ds.cloneWithRows zu verwenden, wenn ich eine Änderung vornehmen

Es scheint jedoch nicht viel Sinn zu machen, einen Cache der Datenstruktur zu behalten, den ich mutieren kann, nur um ihn als Quelle für die unveränderliche Datenstruktur zu verwenden (listForUI: ds.cloneWithRows(t) im folgenden Code), wenn ich will optimistisch die UI aktualisieren (dh zeige die Änderung an, bevor sie auf dem Server gespeichert wird).

Die Alternative (mir auch nicht viel Sinn) scheint zu sein, den Server zu aktualisieren und auf eine Antwort zu warten (ohne einen Cache irgendeiner Art zu halten), wenn ich ein neues Element auf meiner Liste aktualisiere oder hinzufüge , aber das wäre langsam?

Frage: Kann man eine veränderliche Kopie der Daten nicht als Cache speichern, gibt es eine Möglichkeit, ein ui im ​​reagierenden nativen zu aktualisieren?

addNewItemToList: function(){ 

    var t = this.state.items; //my cache of list items 
    var newListItem = {}; 
    newListItem['id'] = 123; 
    t.push(newListItem); //adding-mutating the cache 

    //creating a new immutable ds 
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    this.setState({ 
    listForUI: ds.cloneWithRows(t) 
    }, function(){ 

    //update server with change 
    fetch('http://localhost:8080/accounts/1/lists/3/todos', { 
     method: 'POST', 
     headers: { 
      'Accept': 'application/json', 
      'Content-Type': 'application/json', 
     }, 
     //code ommitted 
    } 

} 

Antwort

1

Nein, ich bin ziemlich sicher, dass es keine andere Art und Weise ist ein Listview-Datenquelle zu aktualisieren, da, wie Sie erklären, es unveränderlich ist. Unveränderbarkeit bedeutet, dass Sie immer eine Kopie von allem machen müssen, bevor Sie es hinzufügen.

Sie erwähnen:

Es ist jedoch nicht viel Sinn zu machen scheint, einen Cache der Datenstruktur zu halten, die ich für den alleinigen Zweck es als Quelle der Verwendung für die unveränderlichen Daten mutieren können Struktur ...

Ich bin nicht wirklich sicher, warum Sie glauben, dass das Halten dieses Cache keinen Sinn ergibt. Ich sehe auch keine Ursache für Leistungsprobleme, da der Cache nur für einen kurzen Moment existiert, während addNewItemToList ausgeführt wird.

+0

Warum denkst du, dass der Cache nur für einen kurzen Moment existiert? Sie müssen jederzeit eine Kopie der Daten für die App für jede Art von Update bereithalten und dann nach jedem Update "cloneWithRows" aufrufen, um die neue unveränderbare Kopie zu erstellen. – Leahcim

+0

Oh, richtig, ich hatte deinen ursprünglichen Post falsch gelesen. Ich denke, das wäre ohne Cache nur möglich, wenn Sie auf die ursprüngliche Datenstruktur zugreifen könnten, die aus der 'dataSource' entnommen wurde, aber das scheint nicht möglich zu sein. –

1

Sie müssen die vorherigen Elemente speichern, wenn Sie ein optimistisches Update rückgängig machen möchten. Um dies zu tun, müssen Sie irgendwie einen Verweis auf die vorherigen Daten "zwischenspeichern" oder speichern.

Sie können optimistischer this.setState in Ihrem addNewItemToList Handler aufrufen und Ihren Zustand aktualisieren (was eine erneute machen), und dann in Ihrem fetch können Sie die Änderung zurück, wenn erforderlich (dh, wenn der Aufruf fehlschlägt):

addNewItemToList: function(id) { 
    // Store current list of items and calculate new list 
    var prevItems = this.state.listForUI.slice(); 
    var newItems = this.state.items.concat([id]); 

    // Optimistically set new items list; will cause a re-render 
    this.setState({ 
     listForUI: this.state.listForUI.cloneWithRows(newItems) 
    }); 

    // Update server with change 
    fetch('http://localhost:8080/accounts/1/lists/3/todos', { 
     method: 'POST', 
     headers: { 
      'Accept': 'application/json', 
      'Content-Type': 'application/json', 
     }, 
     //code ommitted 
    }) 

    // Catch an error and revert change 
    .catch(function (ex) { 
     this.setState({ 
      listForUI: this.state.listForUI.cloneWithRows(prevItems) 
     }); 
    }); 
} 
Verwandte Themen