Mit the mapping
plugin for Knockout Sie der Ansicht Modell aus einem einfachen Javascript-Objekt festlegen können, wie aus einem Ajax-Aufruf zurückgegeben:
var viewModel = ko.mapping.fromJS(data);
// Every time data is received from the server:
ko.mapping.updateFromJS(viewModel, data);
Ich hatte eine fast ähnliche Situation, wo meine Objekte Instanzen von Javascript-Klassen sind. Die Klassen sind ohne Knockout definiert und ich wollte sie modifizieren, um stattdessen Observables zu verwenden.
Ich habe einen kleinen Helfer erstellt, um reguläre Objekte in beobachtbare Objekte umzuwandeln. Sie können entweder die beobachtbaren Felder angeben oder sie im Objekt (Prototyp) festlegen. (Ich dachte, dies automatisch tun, aber ich konnte nicht bestimmen, welches Feld sicher war zu konvertieren und welches nicht.)
(function() {
ko.observableObject = function(object, ko_fields) {
ko_fields = ko_fields || object._ko_fields;
if (!ko_fields) {
return object;
}
for (var f_idx = 0; f_idx < ko_fields.length; f_idx++) {
var field_name = ko_fields[f_idx];
if (object[field_name] && object[field_name].__ko_proto__ !== undefined) {
continue;
}
if (object[field_name] instanceof Array) {
var field_array = object[field_name];
for (var a_idx = 0; a_idx < field_array.length; a_idx++) {
field_array[a_idx] = ko.observableObject(field_array[a_idx]);
}
object[field_name] = ko.observableArray(field_array);
} else {
object[field_name] = ko.observable(object[field_name]);
}
}
return object;
};
})();
Sie es mit Klassen verwenden können, oder mit einfachen Objekten.
// With classes. We define the classes without Knockout-observables
// User.subscriptions is an array of Subscription objects
User = function(id, name) {
this.id = id;
this.name = name;
this.subscriptions = [];
};
Subscription = function(type, comment) {
this.type = type;
this.comment = comment;
});
// Create some objects
var jan = new User(74619, "Jan Fabry");
jan.subscriptions.push(new Subscription("Stack Overflow", "The start"));
jan.subscriptions.push(new Subscription("Wordpress Stack Exchange", "Blog knowledge"));
var chris = new User(16891, "Chris Westbrook");
// We would like to convert fields in our objects to observables
// Either define the fields directly:
ko.observableObject(jan, ['id', 'name', 'subscriptions']);
ko.observableObject(chris, ['id', 'name', 'subscriptions']);
// This will only convert the User objects, not the embedded subscriptions
// (since there is no mapping)
// If you define it in the class prototype, it will work for embedded objects too
User.prototype._ko_fields = ['id', 'name', 'subscriptions'];
Subscription.prototype._ko_fields = ['type', 'comment'];
ko.observableObject(jan);
ko.observableObject(chris);
// It also works with objects that are not created from a class, like your Ajax example
var observable = ko.observableObject({'id': 74619, 'name':'Jan'}, ['id', 'name']);
+1 für große Frage: Knockout + Ajax Howto –