2012-05-26 17 views
9

Sto cercando di risolvere un piccolo problema con la mappatura ko. Lo scenario è che il mio ViewModel è fondamentalmente una raccolta di oggetti. Ciascuno degli oggetti è stato creato da una chiamata JSON, in questo modo:knockout creare un oggetto vuoto da auto-mapped osservabile

var ViewModel = ko.observableArray(); 

$.getJSON(url, function(data) { 
    ViewModel.push(ko.mapping.fromJSON(data)); 
}); 

Questo funziona perfettamente e posso fare ogni sorta di magia nel mio HTML. La domanda è se per esempio voglio aggiungere qualcosa alla mia collezione, diciamo per supportare lo scenario "Aggiungi e modifica" lato client. Mi piacerebbe fare qualcosa di simile:

<input type="button" value="add new" data-bind="click: AddNew" /> 

E vorrei la funzione AddNew nel ViewModel essere qualcosa di simile:

function AddNew() { 
    this.push(// WHAT HERE?); 
} 

Fondamentalmente ho bisogno di spingere un oggetto che è identico all'altro già esistente, ma ovviamente con tutte le proprietà cancellate ...

Stavo pensando a un modo di "clonare" un oggetto dall'elenco e di impostare tutti gli osservabili a vuoto ma non saprei da dove iniziare I ' m paura:/

risposta

6

Se avete intenzione di espandere la funzionalità di modifica sul lato client/ADD allora vi consiglio di formalizzare gli oggetti in una classe js e poi mappare questi oggetti internamente. Questo ti permetterebbe di avere i tuoi metodi di aggiunta sul tuo viewmodel principale e creare facilmente lato client istanze vuote.

Un avvertimento con il plugin mappatura è che per aggiornare gli oggetti che si aspetta quegli oggetti sono stati originariamente mappati dal plugin. Ecco un rapido esempio di come potrebbe essere fatto.

var YourObjectClass = function (config) { 
    var self = this, data; 

    // your default structure goes here 
    data = $.extend({ 
     name: "", 
     id : -1 
    }, config); 

    ko.mapping.fromJS(data, {}, self); 
}; 

var viewModel = function(initialData) { 
    var self = this; 

    ko.mapping.fromJS(initialData, { 
     items: { 
      create : function (options) { 
       return new YourObjectClass(options.data); 
      } 
     } 
    }, self); 

    this.AddNew = function() { 
     self.items.push(new YourObjectClass()); 
    } 
}; 

Spero che questo aiuti.

+1

"Un avvertimento con il plug-in di mappatura è che per l'aggiornamento degli oggetti si aspetta che questi oggetti siano stati originariamente mappati dal plugin. Ecco un rapido esempio di come potrebbe essere fatto." - Se lo avessi saputo prima, mi avrebbe risparmiato un sacco di tempo! – ec2011

0

Sai i campi o hai bisogno di loro copiati da quello che si ottiene dal server? Penso che avresti problemi a iniziare una nuova lista, se così fosse. Si potrebbe semplicemente creare un modello e spingerlo:

var myTemplate = { 
    name: ko.observable(), 
    phone: ko.observable() 
}; 

ViewModel.push(myTemplate); // add empty item 

Non ho mai visto il modello di vista sia una matrice osservabile o osservabili, perché non creare in questo modo?

function ViewModel() { 
    self = this; 
    self.items = ko.observableArray(); 
} 

var myViewModel = new ViewModel(); 
ko.applyBindings(myViewModel); 

$.getJSON(url, function(data) { 
    myViewModel.items.push(ko.mapping.fromJSON(data)); 
}); 
+0

Il secondo modo è quello che sto facendo. Non ero sinceramente dispiaciuto, ma volevo dire che la VM contiene solo una collezione e la riempio esattamente così. Hai ragione, conosco le proprietà dei singoli articoli ma sto usando la mappatura automatica per evitare il fastidio di creare un modello per loro. Se questo è l'unico modo per andare va bene, ma mi chiedevo se ko o la mappatura (o JavaScript da soli) fornito qualche modo di "Newing" un oggetto da quelli già esistenti (forse esplorare i metadati? Clonazione?). – Tallmaris

Problemi correlati