web-dev-qa-db-fra.com

Puis-je lier des entrées de formulaire à des modèles dans Backbone.js sans suivre manuellement les événements de flou?

J'ai une application backbone.js ( www.github.com/juggy/job-board ) où je veux lier mes entrées de formulaire directement à mon modèle (à la Sproutcore).

Est-il possible avec Backbone.js (ou d'autres outils) sans réellement suivre chaque événement de flou sur les entrées et mettre à jour le modèle manuellement? Cela ressemble à beaucoup de code de colle.

Merci,
Julien

62
Julien

Je ne sais pas comment SC le fait, mais probablement ils écoutent aussi les événements.

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

Il existe un moyen encore plus agréable de gérer cela si votre modèle contient de nombreuses propriétés.

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

Il y a une dépendance sur vos éléments d'entrée ayant un id identique au nom de la propriété dans votre modèle.

53
Malcolm Sharman

Je pense que c'est un moyen plus propre (et peut-être plus rapide) de créer un objet à partir d'un élément d'entrée

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

sans jquery:

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

Avez-vous essayé Backbone.ModelBinder? C'est un bel outil pour faire ce dont vous avez besoin: https://github.com/theironcook/Backbone.ModelBinder

12
Bruno Reis

Je travaille sur corset, une bibliothèque de formulaires pour backbone.js inspirée du module Django forms, mais un peu moins ambitieux. Toujours en train de résoudre les problèmes, mais cela finira sur github quand au moins semi-stable et fonctionnel.

Le but du corset est d'avoir des classes de champ facilement sous-classées afin que vous puissiez créer des entrées complexes pour des cas d'utilisation plus complexes (sélections en cascade, etc.). Cette approche rend chaque champ comme une vue distincte, et la vue de formulaire est liée à un modèle et utilise des événements de modification, des événements de flou ou des événements de soumission pour mettre à jour le modèle (configurable, le flou est par défaut). Chaque vue possède une fonction getData remplaçable qui, par défaut, correspond à la fonction jquery .val ().

En utilisant des valeurs par défaut sensibles et une fonction modelFormFactory, nous utilisons un corset (ou le sous-ensemble de celui-ci qui est en fait déjà fait) pour un développement rapide, définissons un modèle en utilisant des noms d'attributs sensibles, utilisez modelFormFactory et vous avez une interface utilisateur d'édition instantanée.

0
Jens Alm

J'ai créé la technique suivante sur mon 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) 

J'ai détaillé les extensions de backbone que vous devez faire sur mon blog

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

il utilise le même style déclaratif que la propriété events pour lier des éléments de formulaire à des attributs de modèle

et voici le code réel implémentant la classe pour vous en 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

    @

Toutes mes excuses si vous n'aimez pas coffeescript. Je fais. Tout le monde est différent :)

0
bradgonesurfing