Могу ли я привязывать входные данные форм к моделям в Backbone.js без ручного отслеживания событий размытия?

У меня есть приложение backbone.js(www.github.com/juggy/job-board), где я хочу привязать свои входные данные формы непосредственно к моей модели (a la Sproutcore).

Возможно ли использование Backbone.js(или других инструментов), не отслеживая каждое событие размытия на входах и обновляя модель вручную? Это похоже на много кода клея.

Спасибо,
Julien

Ответ 1

Я не уверен, как SC это делает, но, вероятно, они тоже слушают события.

window.SomeView = Backbone.View.extend({
  events: {
    "change input.content":  "contentChanged"
  },
  initialize: function() {
    _.bindAll(this, 'contentChanged');
    this.inputContent = this.$('input.content');
  },
  contentChanged: function(e) {
    var input = this.inputContent;

    // if you use local storage save 
    this.model.save({content: input.val()});

    // if you send request to server is prob. good idea to set the var and save at the end, in a blur event or in some sync. maintenance timer.
    // this.model.set({content: input.val()});
  }
});

Ответ 2

Существует еще лучший способ справиться с этим, если ваша модель включает в себя множество свойств.

SampleView = Backbone.View.extend({
    el: "#formEl",

    events: {
        "change input": "changed",
        "change select": "changed"
    },

    initialize: function () {
        _.bindAll(this, "changed");
    },

    changed:function (evt) {
       var changed = evt.currentTarget;
       var value = $(evt.currentTarget).val();
       var obj = {};
       obj[changed.id] = value;
       this.model.set(obj);
    }
 });

Существует зависимость от ваших элементов ввода, имеющих идентификатор так же, как и имя свойства в вашей модели.

Ответ 3

Я думаю, что это более чистый (и, возможно, более быстрый) способ создания объекта из элемента ввода

changed: function(evt) {
  var target = $(evt.currentTarget),
      data = {};
  data[target.attr('name')] = target.val();
  this.model.set(data);
},

без jquery:

changed: function(evt) {
  var target = evt.currentTarget,
      data = {};
  data[target.name] = target.value;
  this.model.set(data);
},

Ответ 5

Я работаю над корсетом, библиотекой форм для backbone.js, созданной модулем форм django, но немного менее амбициозным по своему охвату. Все еще разрабатывает перегибы, но в конечном итоге это будет на github, когда, по крайней мере, полустабильный и функциональный.

Цель корсета - легко подклассифицировать полевые классы, чтобы вы могли создавать сложные входы для более сложных вариантов использования (каскадные выделения и т.д.). Этот подход отображает каждое поле как отдельное представление, а вид формы привязан к модели и использует события изменений, размывает события или отправляет события для обновления модели (настраивается, размытие по умолчанию). Каждое представление имеет переопределяемую функцию getData, которая по умолчанию сопоставляется с функцией jquery.val().

Используя разумные значения по умолчанию и функцию modelFormFactory, мы используем корсет (или его подмножество, которое на самом деле сделано) для быстрой разработки, определите модель с использованием разумных имен атрибутов, используйте modelFormFactory, и у вас есть мгновенный интерфейс редактирования.

Ответ 6

Я создал следующую технику на своем сайте

class FooView extends MyView

  tag: "div"

  modelBindings:

    "change form input.address" : "address"
    "change form input.name"    : "name"
    "change form input.email"   : "email"

  render: ->

    $(@el).html """
      <form>
        <input class="address"/>
        <input class="name"/>
        <input class="email"/>
      </form>
    """

    super

    @


# Instantiate the view 
view = new FooView
  model: new Backbone.Model

$("body").html(view.el) 

Я подробно рассказал о расширениях, которые нужно создать в моем блоге

http://xtargets.com/2011/06/11/binding-model-attributes-to-form-elements-with-backbone-js/

он использует тот же декларативный стиль, что и свойство events для привязки элементов формы для моделирования атрибутов

и вот фактический код, реализующий класс для вас в coffeescript

class MyView extends Backbone.View

  render: ->

    if @model != null
      # Iterate through all bindings
      for selector, field of @modelBindings
        do (selector, field) =>
          console.log "binding #{selector} to #{field}"
          # When the model changes update the form
          # elements
          @model.bind "change:#{field}", (model, val)=>
            console.log "model[#{field}] => #{selector}"
            @$(selector).val(val)

          # When the form changes update the model
          [event, selector...] = selector.split(" ")
          selector = selector.join(" ")
          @$(selector).bind event, (ev)=>
            console.log "form[#{selector}] => #{field}"
            data = {}
            data[field] = @$(ev.target).val()
            @model.set data

          # Set the initial value of the form
          # elements
          @$(selector).val(@model.get(field))

    super

    @

Заявления, если вам не нравится coffeescript. Я делаю. Все разные:)