I’m building an application in Backbone. In my collection model, I have a sync function that fires when a user clicks a button. It submits some form data to the server and the server returns a JSON object containing either a success or error message.
The problem is that I can’t seem to trigger an event in the collection view when the collection model syncs:
Here is the Complete Script:
var RegisterModel = Backbone.Model.extend({url: 'api/process.php', defaults: { contentType: 'input', value: '', inputType: 'text', inputClass: 'required', serverResponseClass: 'alert alert-error', message: ' ', responseType: ' '} });
var RegisterView = Backbone.View.extend({
template: _.template('<p><% if (contentType == "input") { %><input placeholder="<%= label %>" name="<%= inputName %>" id="<%= inputName %>" value="<%= value %>" type="<%= inputType %>" class="<%= inputClass %>"/><% } %><% if (contentType == "button") {%> <input type="<%= inputName %>" class="<%= btnClass %>" id="<%= inputName %>"<% } %></p>'),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var RegisterCollection = Backbone.Collection.extend({
model: RegisterModel,
url: 'api/process.php',
updateModels: function (){
this.forEach(this.updateModel, this);
},
updateModel: function(registerModel) {
var inputName = '#'+registerModel.get('inputName');
var userInput = $(inputName).val();
registerModel.set({value: userInput});
},
clearErrors: function() {
var musketeers = this.where({contentType: "serverResponse"});
this.remove(musketeers);
},
syncCollection: function() {
Backbone.sync.call(this, 'create', this);
}
});
var RegisterCollectionView = Backbone.View.extend({
initialize: function(){
this.collection.on('reset', this.addAll, this);
this.collection.on('add', this.addAll, this);
this.collection.on('sync', this.onModelSaved);
/* this.collection.on('remove', function(){registerCollection.fetch(); }, this); */
},
el: "#backboneContainer",
events: {
"click #submit" : "validate",
},
validate: function(e) {
e.preventDefault();
if ($("#register").valid() === true) {
this.collection.clearErrors();
this.collection.updateModels();
this.collection.syncCollection();
}
},
errorOverlay: function(errorTitle, errorContent) {
$.notification({
title: errorTitle,
content: errorContent,
timeout: 5000,
icon: "!",
error: true,
border: false
});
},
onModelSaved: function () {
console.log('hello world!');
alert('hello world!');
},
successMessage: function(message) {
$.fn.modal({
layout: "elastic",
url: undefined,
content: message,
padding: "50px",
animation: "fadeInDown"
});
this.$el.append('<span class="icon">=</span>');
},
addOne: function(registerModel){
var registerView = new RegisterView({model: registerModel});
this.$el.append(registerView.render().el);
},
buildForm: function(registerModel) {
var registerView = new RegisterView({model: registerModel});
$('#register').append(registerView.render().el);
},
addAll: function(){
this.$el.empty();
this.$el.append('<div class="con"><div class="section current" title="Our First Section" ><div class="col_12"><h1>Piecharter.com</h1></div><div class="carton col_4"><h2>Registration</h2><div class="content"><form id="register" method="post"></form></div></div></div></div>');
this.collection.forEach(this.buildForm, this);
$("#register").validate();
/* this.$el.append('); */
},
render: function(){
this.addAll();
return this;
}
});
$('.modal').live("click", function () {
this.remove();
$('#overlays').hide();
});
/*VALIDATION HERE ~*/
jQuery.validator.addClassRules("username", {
minlength: 7,
maxlength: 21
});
jQuery.validator.addMethod("password", function( value, element ) {
var result = this.optional(element) || value.length >= 1 && /\d/.test(value) && /[a-z]/i.test(value);
if (!result) {
var validator = this;
setTimeout(function() {
validator.blockFocusCleanup = true;
element.focus();
validator.blockFocusCleanup = false;
}, 1);
}
return result;
}, "Your password must be at least 7 characters long and contain at least one number and one character.");
I know the collection is successfully syncing, so the problem must be with the way I am listening to the sync event in my collection view. Any ideas what is wrong here? I’ve looked over the documentation and I can’t find any problems with the way I have structured this.
You left out the
thiswhen you tried to bind “onModelSaved”, so instead of referencing the object’s “onModelSaved” method, you referenced the global “onModelSaved” variable (which almost certainly doesn’t exist).Try: