Domanda

Ho cercato di capirlo per un bel po 'di tempo. Non sono riuscito a trovare nulla che affronta questo problema, ma per favore correggimi se sbaglio.

Il problema: Ho dei dati da un API JSON su, con una matrice nidificata / struttura oggetto. Io uso la mappatura per riempire inizialmente il modello con i miei dati. Per aggiornare questo, voglio estendere il modello se arriva nuovi dati o aggiornare i dati esistenti.

Per quanto ho scoperto, la chiave di opzione di mappatura, dovrebbe fare questo trucco per me, ma potrei aver frainteso la funzionalità delle opzioni di mappatura.

Ho creato il problema per essere rappresentato da questo esempio:

var userMapping = {
    key: function(item) {
        return ko.utils.unwrapObservable(item.id);
    }
};

// JSON call replaced with values
var viewModel = {
    users: ko.mapping.fromJS([], userMapping)
};

// Should insert new - new ID?
ko.mapping.fromJS([{"id":1,"name":"Foo"}, {"id":2,"name":"Bar"}], userMapping, viewModel.users);

// Should only update ID#1 - same ID?
ko.mapping.fromJS([{"id":1,"name":"Bat"}], userMapping, viewModel.users);

// Should insert new - New ID?
ko.mapping.fromJS([{"id":3,"name":"New"}, {"id":4,"name":"New"}], userMapping, viewModel.users);

ko.applyBindings(viewModel);​
.

Fiddle: http://jsfiddle.net/mikaelbr/gdja7/

Come puoi vedere, la prima riga inserisce i dati. Tutto bene. Ma quando provo ad aggiornare, sostituisce il contenuto. Lo stesso per la terza mappatura; Sostituisce il contenuto, invece di sostenerlo.

Sto usandolo sbagliato? Dovrei provare ad estendere il contenuto "manualmente" prima di usare la mappatura?

Modifica soluzione:
Ho risolto questo caso avendo un secondo array di helper che memorizza tutti i modelli attuali. Su nuovi dati ho esteso questo array e aggiornato il modello di visualizzazione per contenere gli elementi accumulati.

On Update (nel mio caso un messaggio WebSocket), ho loopato attraverso i modelli, ha cambiato il contenuto della voce in questione e il metodo usato ValueSasmutated () per dare avviso di valore modificato al libretto di knockout.

È stato utile?

Soluzione

From looking at your example code the mapping plugin is behaving exactly as I would expect it to. When you call fromJS on a collection you are effectively telling the mapping plugin this is the new contents of that collection. For example:

On the second line, How could it know whether you were updating or whether you had simply removed id:2?

I can't find any mention of a suitable method that treats the data as simply an update, although you could add one. Mapped arrays come with some helpful methods such as mappedIndexOf to help you find particular items. If you receive an update data set simply loop through it, find the item and update it with a mapping.fromJS call to that particular item. This can easily be generalized into reusable method.

Altri suggerimenti

You can use ko.mapping.updateFromJS() to update existing values. However, it does not add new values so that would be a problem in your instance. Take a look at the link below for more details.

Using updateFromJS is replacing values when it should be adding them

Yes, you should first collect all data into a list or array and then apply the mapping to that list. Otherwise you are going to overwrite the values in your viewModel.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top