2013-02-20 11 views
14

ho il seguente modello:Come escludere alcuni oggetti di Knockoutjs tojs()

var model = { 
    A: 'One', 
    B: 'Two', 
    C: 'Three' 
}; 

mi legano vari elementi dell'interfaccia utente a questi campi, che funziona alla grande. Tuttavia, posso convertire il modello di nuovo ad un oggetto JavaScript in modo da poter salvare le modifiche al server:

var goingToServer = ko.toJS(model); 

goingToServer includerà proprietà A, B e C. Tuttavia, diciamo proprietà C è un pezzo enorme di dati quello non cambierà mai. Mi piacerebbe evitare di inviare questo al server.

C'è un modo per rendere toJS()solo comprendono un insieme predefinito di campi durante la conversione di un modello nuovo ad un oggetto JavaScript?

Una cosa che ho indagato è lo Knockout Mapping plugin. Ha un ambiente chiamato includono che è documentato come tale:

Quando la conversione del modello di vista posteriore di un oggetto JS, per impostazione predefinita il plugin mappatura include solo le proprietà che facevano parte del vostro modello di vista originale , tranne che includerà anche la proprietà _destroy generata da Knockout anche se non faceva parte dell'oggetto originale . Tuttavia, è possibile scegliere di personalizzare questo array:

Tuttavia, sembra questo plugin non funziona come documentato, come ko.mapping.toJS() sarà ancora includere A, B e C, anche se passo in una serie di include['A', 'B'] . Immagino che questa funzione includa i campi aggiuntivi che non erano nel modello originale.

Esiste un modo per escludere determinate proprietà quando si converte un modello su un oggetto JavaScript, a corto di fare qualcosa di hacky come generare l'oggetto e rimuovere manualmente le proprietà che non desidero prima di inviare al server?

risposta

23

Hai provato la parola chiave ignore? E 'un uso simile a quello includere:

var mapping = { 
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"] 
} 
var viewModel = ko.mapping.toJS(data, mapping); 

Si potrebbe utilizzare ignorare quando si esegue la mappatura originale dei dati del server, allora non sarà sul vostro oggetto a tutti quando si converte di nuovo a JS .

+0

che non funziona, come allora, non è possibile associare ad esso a tutti. –

+0

Hai provato? Poiché la documentazione non menziona se è possibile ignorare quando si torna agli oggetti JS. –

+0

Sì, l'ho appena provato. Quando "ignoro" il campo "Note" e quando chiamo applyBindings, ottengo immediatamente un'eccezione che il campo "Note" non è stato trovato nel modello. –

2

Ok, ho trovato una soluzione che funziona anche se spero che ci sia un approccio migliore. Il trucco è di ignorare questi campi nel plug-in di mappatura, quindi aggiungerli manualmente come campi calcolati. I campi calcolati non finiranno mai nell'oggetto JavaScript generato quando viene chiamato toJS.

// Utility function to quickly generate a computed field 
ko.readonly = function (value) 
{ 
    return ko.computed(function() 
    { 
     return value; 
    }); 
}; 

// View Model 
var ViewModel = function (project) 
{ 
    var readonly = ['B', 'C', 'D']; // Fields I want to ignore 
    var mapping = { 
     'ignore': readonly //Read-only properties, we'll add these manually as computed fields 
    }; 

    // Use Mapping plugin to make everything observable, except the fields above 
    ko.mapping.fromJS(project, mapping, this); 

    // Now loop through the read only array and add these fields in as computed 
    for(var i = 0; i < readonly.length; i++) 
    { 
     var field = readonly[i]; 
     this[field] = ko.readonly(project[field]); 
    } 
} 

ora posso associare a questi modelli vista come normale:

ko.applyBindings(new ViewModel(data)); 
3

Se abbiamo un complesso istanza di oggetto modello in VM.Pagamento riferimento osservabile come:

{ 
 
    "Summary": { 
 
     "Count": 12, 
 
     "PaymentAmount": 1500, 
 
     "PaymentMethod": "Cheque", 
 
     "PaymentDate": "2015-04-08T22:38:48.552Z", 
 
     "AgentOid": 1208795, 
 
     "AgentName": "Asere Ware" 
 
    } 
 
    //[...] 
 
}

e devono ignorare solo alcune proprietà intrinseche, quindi:

var mapping = { 
 
    'ignore': ['Summary.PaymentMethod', 'Summary.PaymentDate'] //avoid lost some initialized values. 
 
}; 
 
// map updating existing observable (Payment) under my ViewMode (vm) with source "data" JSON object. 
 
ko.mapping.fromJS(data, mapping, vm.Payment);

e questo è il risultato vm. Contenuto del pagamento, dove sono visualizzati solo PaymentMethod e PaymentDate:

{ 
 
    "Summary": { 
 
     "Count": 0, 
 
     "PaymentAmount": 0, 
 
     "PaymentMethod": "Cheque", 
 
     "PaymentDate": "2015-04-08T22:38:48.552Z", 
 
     "AgentOid": undefined, 
 
     "AgentName": undefined 
 
    } 
 
    //[...] 
 
}

Problemi correlati