Визуализация с перезаписанными геттерами в Backbone - PullRequest
0 голосов
/ 24 ноября 2011

Я создаю небольшое приложение Backbone.js и добавил несколько пользовательских методов получения к одной из моделей (например, метод получения имени возвращает объединенные имя и фамилию):

PersonModel = Backbone.Model.extend({
  get: function (attr) {
    if (typeof this[attr] == 'function') {
      return this[attr]();
    }
    return Backbone.Model.prototype.get.call(this, attr);
  },

  name: function() {
    return firstName + " " + lastName;
  }
})

Теперь я могуиспользуйте person.get("name"), чтобы получить имя, хорошо.Однако, когда я вызываю toJSON для модели, эти значения не включаются (и я полагаю, что это имеет смысл).Проблема в том, что я использую это для отображения моих представлений:

this.template({people: this.collection.toJSON()});

Какой лучший способ сделать это в Backbone.js?Создание JSON вручную с перезаписанными получателями?

Спасибо!

Ответы [ 2 ]

5 голосов
/ 24 ноября 2011

Вы можете предоставить свой собственный метод toJSON в PersonModel:

toJSON: function() {
    var attr = Backbone.Model.prototype.toJSON.call(this);
    attr.name = this.name();
    return attr;
}

Коллекция toJSON просто вызывает toJSON для каждой модели:

// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON : function() {
  return this.map(function(model){ return model.toJSON(); });
},

, поэтому добавление вашей toJSON к вашей модели должно работать.

Вы также можете добавить name в качестве реального атрибута, а затем настроить метод validate вашей модели, чтобы обновить name, если firstName или lastName изменится, и игнорировать любые прямые попытки изменить name или жаловаться на «попытку изменить атрибут только для чтения», когда кто-то пытается передать name изменение на set. Ничто не говорит о том, что validate не может изменить заданный объект атрибута, поэтому вы можете получить {firstName: 'x'} и изменить его на {firstName: 'x', name: 'x ' + this.get('lastName')} до возвращения validate. Это было бы немного злоупотреблением validate, но нет явного запрета на validate изменение набора атрибутов, и это единственный доступный хук, который у вас есть. Я полагаю, вы могли бы заставить модель прослушивать события изменения самостоятельно firstName и lastName, а затем вызывать set({name: ...}), но тогда у вас могут возникнуть проблемы с упорядочением событий, если кто-то другой наблюдает только за именем и фамилией.

0 голосов
/ 07 августа 2014

Я решил расширить базовую модель и сделать так, чтобы все модели моих приложений расширялись от базовой модели, которая включает метод, поэтому разрешите задавать виртуальные атрибуты, которые объединяются в модели toJSON метод.

  toJSON: function() {
    return _.extend(toJSON.__super__.constructor.apply(this, arguments), this.getVirtualAttributes());
  },
  getVirtualAttributes: function() {
    var attrs, key;
    attrs = {};
    for (key in this.virtualAttributes) {
      attrs[key] = this.virtualAttributes[key].call(this);
    }
    return attrs;
  }

Это позволяет вам определять объект virtualAttributes в модели, который можно использовать для извлечения виртуального / динамического атрибута.

virtualAttributes: {
  email_length: function() {
    return this.get("email").length
  }
}
...