javascript - making fields observable after ajax retrieval in knockout.js -
i wondering how can make fields observables in knockout.js ajax call without having define whole object in viewmodel. possible? here have far:
var viewmodel = { lines: new ko.observablearray([]) }; function refreshlist(ionum) { var data = {}; data['ionum'] = ionum; $.ajax({ url: 'handlers/getlines.ashx', data: data, cache: false, datatype: 'json', success: function(msg) { viewmodel.lines(msg); //here attempting make email address field observable /*for (var = 0; < msg.length; i++) { viewmodel.lines()[i].emailaddress = new ko.observable(msg[i].emailaddress); }*/ //alert(viewmodel.lines[0].emailaddress); //ko.applybindings(viewmodel); } }); }
with the mapping
plugin knockout can define view model plain javascript object, returned ajax call:
var viewmodel = ko.mapping.fromjs(data); // every time data received server: ko.mapping.updatefromjs(viewmodel, data);
i had similar situation, objects instances of javascript classes. classes defined without knockout in mind, , wanted modify them use observables instead.
i created small helper convert regular objects observable objects. can either specify observable fields, or set them in object (prototype). (i thought of doing automatically, not determine field safe convert , 1 not.)
(function() { ko.observableobject = function(object, ko_fields) { ko_fields = ko_fields || object._ko_fields; if (!ko_fields) { return object; } (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]; (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; }; })();
you can use classes or plain objects.
// classes. define classes without knockout-observables // user.subscriptions 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 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"); // convert fields in our objects observables // either define fields directly: ko.observableobject(jan, ['id', 'name', 'subscriptions']); ko.observableobject(chris, ['id', 'name', 'subscriptions']); // convert user objects, not embedded subscriptions // (since there no mapping) // if define in class prototype, work embedded objects user.prototype._ko_fields = ['id', 'name', 'subscriptions']; subscription.prototype._ko_fields = ['type', 'comment']; ko.observableobject(jan); ko.observableobject(chris); // works objects not created class, ajax example var observable = ko.observableobject({'id': 74619, 'name':'jan'}, ['id', 'name']);
Comments
Post a Comment