Knockout映射对象的响应

时间:2016-01-29 21:16:55

标签: knockout.js

我有一个像这样的用户对象:

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);
        });
    };

虽然上述作品非常棒,但实际上很长。是否有更短的方法来绑定对象?

2 个答案:

答案 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;