我有一个像这样的用户对象:
var userModel = {
Id: ko.observable(),
Email: ko.observable().extend({ email: true, required: true, maxLength: 200 }),
FirstName: ko.observable().extend({ required: true, minLength: 2, maxLength: 200 }),
LastName: ko.observable().extend({ required:true, minLength: 2, maxLength: 200 }),
DefaultLanguage: ko.observable(),
Phone: ko.observable().extend({phoneUS:true}),
AvatarUrl: ko.observable(),
Claims: ko.observableArray()
};
我正在加载一个响应,并希望将响应绑定到该对象。响应的格式与模型完全相同:
self.user = userModel;
self.loadData = function (params) {
$.get('/api/user/' + params.id).then(function (data) {
console.log('GET User', data);
self.user.Id(data.Id);
self.user.Email(data.Email);
self.user.FirstName(data.FirstName);
self.user.LastName(data.LastName);
self.user.Phone(data.Phone);
self.user.DefaultLanguage(data.DefaultLanguage);
self.user.AvatarUrl(data.AvatarUrl);
self.user.Claims(data.Claims);
});
};
虽然上述作品非常棒,但实际上很长。是否有更短的方法来绑定对象?
答案 0 :(得分:2)
您可以使用javascript反射
$.get('/api/user/' + params.id).then(function (data) {
for(var i in data){
if(data.hasOwnProperty(i) && self.user.hasOwnProperty(i))
{
self.user[i](data[i]);
}
}
});
这可以移动到一个函数中,使事情变得更容易。当您拥有可观察对象的嵌套结构以及可观察和标准属性的组合时,它会变得更加复杂。但根据你的例子,这将有效。
另外。 ko.mapping.fromJS会起作用,但有时会很痛苦。
答案 1 :(得分:0)
我喜欢使用的模式是水合物/再水合物。 Here is a codepen证明了这一点。
var User = function(init) {
var self = this;
self.firstName = ko.observable();
self.lastName = ko.observable();
self.city = ko.observable();
this.update = function(data) {
data = data || {};
Object.keys(data).forEach(function(key) {
self[key](data[key]);
});
}
this.update(init);
}
这样,任何人都可以根据需要轻松地进行更新。
setTimeout(function() {
user.update({
firstName: 'Tim',
lastName: 'Moran',
city: 'Portland'
})
}, 2000)
然而,如果在很多模型上完成,这可能会变得乏味,因此您可以将其拉入基础模型。
var baseViewModel = {
update: function(data) {
data = data || {};
var self = this;
Object.keys(data).forEach(function(key) {
self[key](data[key]);
});
}
}
var User = function(init) {
var self = this;
self.firstName = ko.observable();
self.lastName = ko.observable();
self.city = ko.observable();
this.update(init);
};
User.prototype = baseViewModel;