Durante la creazione di un modello di visualizzazione per Knockout, qual è la differenza qui? Vedo queste diverse implementazioni e ne ho provate alcune e alcune non funzionano allo stesso modo.
//the most common example.
function ViewModel(data){
data = data || {}; var self = this; //note self = this
self.property1 = ko.observable(data.property1 || null);
}
//this one uses a var
var ViewModel = function(data) {
data = data || {}; var self = this; //note self = this
self.property1 = ko.observable(data.property1 || null);
}
//this one uses a var, returns itself, and self isn't "this"
var ViewModel = function(data){
data = data || {}; var self = {}; //note self is empty object
self.property1 = ko.observable();
if (data.property1){self.update(data);};
self.update = function(){self.property1 = data.property1 || null);};
return self;
}
Ho notato che con il secondo modello, ho avuto problemi a cercare di fare riferimento a $ parent nella parte di HTML che lega i dati. L'unico che sembra funzionare in modo affidabile per questo è l'ultimo modello (e ho capito il bit .update, ti permette di aggiornare anche il modello viewmodel).
C'è una vera differenza qui? Ho solo notato che con l'ultimo esempio, se sostituisco self = {}
con self=this
, ottengo problemi con $ parent e simili nel data-binding in HTML (devo ammettere che il mio viewmodel era molto più complesso, costruito da più osservabili per osservabili). Ricordo anche di avere problemi con le funzioni calcolate non visualizzate in base al tipo che ho usato. Era tutto molto confuso (e difficile eseguire il debug di una struttura di oggetti ko'd, funzioni ovunque! ).
Ecco cosa ho finito per fare:
//this is the "main" viewmodel, what gets .applyBindings()'d
var FulfillRequistionRequestModel = function (data) {
data = data || {}; var self = {};
self.RequisitionId = ko.observable(data.RequisitionId || null);
self.FulfillItemList = ko.observableArray(
ko.utils.arrayMap(data.FulfillItemList, function (item_list) { return new FulfillItemModel(item_list); })
);
self.NumberOfItems = ko.computed(function () { return self.FulfillItemList().length; });
//add-remove FullfillItem in FulfillItemList (this is per line number)
self.removeItemFromList = function (fulfill_item) { self.FulfillItemList.remove(fulfill_item); };
self.addItemToList = function () { self.FulfillItemList.push(new FulfillItemModel()); };
//allow self updates
self.update = function (data) {
data = data || {};
self.FulfillItemList.removeAll(); self.RequisitionId(data.RequisitionId || null);
if (data.FulfillItemList) {
$.each(data.FulfillItemList, function (i, item) {
self.FulfillItemList.push(new FulfillItemModel(item));
});
}
}; if (data) { self.update(data); } //this handles first-construction (.applyBinding)
return self;
};
//an observable (array'd in main vm)
var FulfillItemModel = function (data) {
data = data || {}; var self = {};
self.BoxNumber = ko.observable(data.BoxNumber || null);
self.LineNumber = ko.observable(data.LineNumber || null);
self.SourceBin = ko.observable(new BinModel(data.SourceBin) || null);
self.ItemDetailList = ko.observableArray(
ko.utils.arrayMap(data.ItemDetailList, function (item_list) { return new ItemDetailModel(item_list); })
);
self.NumberOfItems = ko.computed(function () {return self.ItemDetailList().length;});
//add-remove something from ItemDetailList (ItemDetail)
self.removeItemFromList = function (item) { self.ItemDetailList.remove(item); };
self.addItemToList = function () { self.ItemDetailList.push(new ItemDetailModel()); };
return self;
};
//an observable two deep
var ItemDetailModel = function(data) {
data = data || {}; var self = {};
self.Part = ko.observable(data.Part || null);
self.Owner = ko.observable(data.Owner || null);
self.Condition = ko.observable(data.Condition || null);
self.Bcn = ko.observable(data.Bcn || null);
self.SerialNumber = ko.observable(data.SerialNumber || null);
self.Quantity = ko.observable(data.Quantity || null);
return self;
};
TLDR : Quindi suppongo che cosa mi stia chiedendo, senza veramente sapere abbastanza su come funziona JS (so abbastanza per fare danni, oltre a 10 danni in più - ma non come funziona internamente, o prototipazione, ecc.). Qual è la scelta migliore per questo?
Il motivo per cui utilizzo .update, è perché mi piace essere in grado di aggiornare l'intero modello (penso guardando un cliente e tutti i suoi ordini e i loro clienti, ecc.) e scegliere i clienti al volo da un elenco. ko.mapping
rende questo facile, non tanto quando lo costruisci. In questo modo, posso solo var myModel = new ViewModel(data);
o più tardi fare un myModel.update(new_data);
. (So che c'è una funzionalità di ko.extend - ma non ho mai potuto farlo funzionare correttamente, neanche provando l'esempio di RP).