2012-01-10 17 views
9

Ho un problema mappatura di un oggetto JSON ricevuto dal server in un Javascript-oggetto predefinito che contiene tutte le funzioni necessarie che vengono utilizzati in bindingKnockout.js mappatura JSON oggetto JavaScript Object

codice Javascript è il

dopo

function Person(FirstName, LastName, Friends) { 
    var self = this; 
    self.FirstName = ko.observable(FirstName); 
    self.LastName = ko.observable(LastName); 
    self.FullName = ko.computed(function() { 
     return self.FirstName() + ' ' + self.LastName(); 
    }) 
    self.Friends = ko.observableArray(Friends); 
    self.AddFriend = function() { 
     self.Friends.push(new Person('new', 'friend')); 
    }; 
    self.DeleteFriend = function (friend) { 
     self.Friends.remove(friend); 
    };  
} 

var viewModel = new Person(); 

$(document).ready(function() { 
    $.ajax({ 
     url: 'Home/GetPerson', 
     dataType: 'json', 
     type: 'GET', 
     success: function (jsonResult) { 
      viewModel = ko.mapping.fromJS(jsonResult); 
      ko.applyBindings(viewModel); 
     } 
    }); 
}); 

HTML:

<p>First name: <input data-bind="value: FirstName" /></p> 
<p>Last name: <input data-bind="value: LastName" /></p> 
<p>Full name: <span data-bind="text: FullName" /></p> 
<p>#Friends: <span data-bind="text: Friends().length" /></p> 
@*Allow maximum of 5 friends*@ 
<p><button data-bind="click: AddFriend, text:'add new friend', enable:Friends().length < 5" /></p> 
<br> 
@*define how friends should be rendered*@ 
<table data-bind="foreach: Friends"> 
    <tr> 
     <td>First name: <input data-bind="value: FirstName" /></td> 
     <td>Last name: <input data-bind="value: LastName" /></td> 
     <td>Full name: <span data-bind="text: FullName" /></td> 
     <td><button data-bind="click: function(){ $parent.DeleteFriend($data) }, text:'delete'"/></td> 
    </tr> 
</table> 

Il mio codice ServerSide MVC per ottenere i dati iniziali si presenta come:

0.123.

Sto cercando di utilizzare il plug-in di mappatura per caricare Json nel mio oggetto Javascript in modo che tutto sia disponibile per i binding (la funzione di aggiunta e le proprietà calcolate sugli oggetti Friend).

Quando uso il plugin di mappatura non sembra funzionare. Quando si utilizza il plug-in, il metodo AddFriend non è disponibile durante l'associazione. È possibile popolare l'oggetto Persona JavaScript utilizzando il plug-in di mappatura o tutto deve essere eseguito manualmente?

risposta

11

È possibile esaminare le opzioni di associazione di passaggio al plug-in di mappatura, in particolare una richiamata create come descritto here.

Qualcosa di simile:

var mapping = { 
    create: function(options) { 
     var person = options.data, 
      friends = ko.utils.arrayMap(person.Friends, function(friend) { 
       return new Person(friend.FirstName, friend.LastName); 
      }); 

     return new Person(person.FirstName, person.LastName, friends); 
    } 
}; 

Esempio: http://jsfiddle.net/rniemeyer/5EWDG/

Tuttavia, in questo caso, non si ottiene un sacco di potenza dal plugin mappatura e si può solo farlo senza chiamando il Costruttore persona stesso e mappatura dell'array Amici su oggetti Person nel costruttore come: http://jsfiddle.net/rniemeyer/mewZD/

Un'altra nota dal codice HTML: assicurarsi che per gli elementi che contengono conte nt, che specifichi i tag iniziale e finale (span e button non erano nel codice). KO avrà problemi se non li specifichi correttamente.

+0

Grazie mille! La tua risposta ha chiarito come funziona la mappatura. – DiederikTiemstra

+0

Ryan, mi sono chiesto l'utilità del plug-in di mappatura una volta che hai iniziato a costruire i tuoi costruttori (come il tuo commento "non hai molta potenza dal plugin di mappatura"). Ho intrapreso un percorso sbagliato quando inizio a utilizzare un costruttore? Se non utilizzo un costruttore, non so come gestire al meglio l'accodamento dei dati mappati con i dati inseriti dall'utente. Con un costruttore posso gestire l'input dell'utente, controllare gli errori, la sicurezza, ecc. Sto solo andando con knockout e voglio andare nel modo giusto. Pensieri? – eh1160

+2

Se si desidera il miglior controllo, allora ritengo che farlo da solo con i costruttori sia l'approccio migliore. I callback 'create' del plugin di mappatura ti permettono di aggiungere le tue proprietà a vari livelli, ma non mi sembra mai così pulito. Il plugin di mappatura è ottimo quando si desidera trasformare una struttura in oggetti osservabili senza scrivere molto codice reale client-sie. –