Posso vincular entradas de formulário aos modelos no backbone.js sem rastrear manualmente os eventos do Blur?

StackOverflow https://stackoverflow.com/questions/4074636

Pergunta

Eu tenho um aplicativo backbone.js (www.github.com/juggy/job-board) onde eu quero vincular minhas entradas de formulário diretamente ao meu modelo (uma la sproutcore).

É possível com o backbone.js (ou outras ferramentas) sem rastrear cada eventos do Blur nas entradas e atualizar o modelo manualmente? Isso parece muito código de cola.

Obrigado,
Julien

Foi útil?

Solução

Não tenho certeza de como o SC faz isso, mas provavelmente eles ouvem eventos também.

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

Outras dicas

Existe uma maneira ainda melhor de lidar com isso se o seu modelo incluir muitas propriedades.

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

Existe uma confiança nos seus elementos de entrada com um ID da mesma forma que o nome da propriedade em seu modelo.

Eu acho que esta é uma maneira mais limpa (e talvez mais rápida) de criar um objeto a partir de um elemento de entrada

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

Sem jQuery:

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

Você já experimentou backbone.modelbinder? É uma boa ferramenta para fazer o que você precisa: https://github.com/theironcook/backbone.modelbinder

Estou trabalhando no Corset, uma biblioteca de formulários para backbone.js inspirada no módulo Django Forms, mas um pouco menos ambicioso em escopo. Ainda está trabalhando nas torções, mas acabará no GitHub quando pelo menos semi-estável e funcional.

O objetivo do espartilho é ter classes de campo facilmente subclassem para que você possa criar entradas complexas para casos de uso mais complexos (selecionamentos em cascata, etc.). Essa abordagem renderiza cada campo como uma visualização separada, e a visualização do formulário está vinculada a um modelo e usa eventos de alteração, eventos desbotados ou enviar eventos para atualizar o modelo (configurável, o Blur é padrão). Cada visualização possui uma função getData substituível que, por mapas padrão, na função jQuery .Val ().

Usando padrões sensíveis e uma função modelformFactory, usamos o espartilho (ou o subconjunto de ela que ainda é feito) para desenvolvimento rápido, defina um modelo usando nomes de atributos sensíveis, use o ModelfformFactory e você terá a UI de edição instantânea.

Eu criei a seguinte técnica no meu site

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) 

Eu detalhei as extensões para a espinha dorsal que você precisa fazer no meu blog

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

Ele usa o mesmo estilo declarativo que a propriedade Events para vincular elementos de formulário para modelar atributos

E aqui está o código real implementando a classe para você no 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

    @

Appologias se você não gosta de CoffeeScript. Eu faço. Todo mundo é diferente :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top