2012-03-09 3 views
17

У меня есть сценарий, в котором данные, обрабатываемые на клиенте, представлены и взаимодействуют с ним по-другому, чем на сервере.Вычислимые свойства в магистральной сети

Рассмотрите приведенный ниже event ресурс, возвращенный с сервера.

{ 
    "id": 123, 
    "start_at": 1331336004906, 
    "end_at": 1331337704906 
} 

И следующий шаблон для редактирования:

<form> 
    <!-- Notice how date and time are separated in the interface --> 
    <input type="text" name="start_date" value="{{start_date}}" /> 
    <input type="text" name="start_time" value="{{start_time}}" /> 

    <!-- Instead of asking for an end date/time, we ask for the duration --> 
    <input type="text" name="duration" value="{{duration}}" /> 

    <input type="submit" /> 
</form> 

Как бы идти о лечении start_date, start_time и duration как атрибуты в моей Backbone модели без отправки их на сервер? Могу ли я изменить .toJSON()?

+0

что проблема с форматом события Ressource, Арент они временные метки? – mpm

+0

См. Также: http://stackoverflow.com/questions/10648990/how-to-access-a-calculated-field-of-a-backbone-model-from-handlebars-template –

ответ

4

Ваша модель должна соответствовать как можно ближе к тому, что у вас есть на стороне сервера. Поэтому придерживайтесь start_at и end_at. Это значительно упростит ваши операции sync().

На Просмотр вашей формы редактирования в, вы можете:

  1. Compute start_date, start_time, duration с помощью простых функций и вызывать их в шаблоне.
  2. Преобразование в start_at и end_at при отправке.
+1

Не помещает это в Вид что приведет к большому количеству избыточного кода? Я буду использовать одни и те же виртуальные атрибуты по всему сайту, где одно событие имеет несколько представлений, которые показывают его. – bloudermilk

+0

Не требуется избыточность. Сделайте базовый вид и увеличьте его. – ggozad

+1

Хороший звонок! Я также думаю, что образец декоратора может удовлетворить эту проблему. – bloudermilk

6

Мы очень привыкли посылать model.toJSON() в кормить шаблон. И этот метод очень сложно перезаписать, потому что он используется другими компонентами.

Но мы можем кормить шаблон с настраиваемым model.toJSONDecorated() метод, который может выглядеть следующим образом:

# in your Backbone.Model 
toJSONDecorated: function(){ 
    return 
    _.extend( 
     this.toJSON(), 
     { 
     start_date : Utils.dateFromDate(this.get("start_at")), 
     start_time : Utils.timeFromDate(this.get("start_at")), 
     duration : Utils.youGetTheIdea(:)) 
     } 
    ); 
} 

Конечно, это нарушает несколько моделей, я могу жить с этим, если вы не можете переместите эту логику на класс Decorator, как предложили люди в других ответах.

5

У вас есть несколько вариантов:

  • Override toJSON вернуть вычисленная duration

  • Создание метода duration() на Backbone Model. Единственный недостаток, который вы должны назвать его по-другому (obj.duration() вместо obj.get('duration')). По вашему мнению, что руки obj.toJSON() в шаблон, смешайте в duration атрибуте

  • Использование https://github.com/asciidisco/Backbone.Mutators (или аналогичный), чтобы создать производный поглотитель для продолжительности

+0

Спасибо. Обычно я использую описанный подход, но я не знал Мутаторов: он выглядит очень полезным и хорошо выполненным. –

22

Я использую комбинацию Initialize() совместно с прослушивателями событий изменений обновлять производные атрибуты. Идея состоит в том, чтобы сначала вычислить атрибуты при инициализации модели, а во-вторых, чтобы модель прослушивала свои собственные изменения и соответствующим образом обновляла атрибуты.

Мое решение выглядит примерно так:

MyModel: Backbone.Model.extend({ 
    initialize: function() { 
     this.updateDerivedAttributes(); 
     this.on('change:start_at', this.updateDerivedAttributes, this); 
    }, 
    updateDerivedAttributes: function() { 
     this.set({ 
      start_date: Utils.dateFromDate(this.get("start_at")), 
      start_time: Utils.timeFromDate(this.get("start_at")), 
      duration: Utils.youGetTheIdea() 
     }, {silent:true}); 
    } 
}); 
Смежные вопросы