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
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()});
}
});
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.
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);
},
Avez-vous essayé Backbone.ModelBinder? C'est un bel outil pour faire ce dont vous avez besoin: https://github.com/theironcook/Backbone.ModelBinder
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.
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 :)