问题
I am experiencing a really interesting problem with backbone, I have a function like this in one of my views:
addpeople :function(){
var authArray = _.clone(this.model.get("authorizedUsers"));
var values = $(".add-input").val().split(",");
values.forEach(function(value) {
authArray.push(value);
});
this.model.set("authorizedUsers" , authArray);
this.model.save();
},
this function gets called when a button is clicked. This version of the function triggers a change
event because I am cloning my array, but for some reason this.model.save()
never gets called, aka the server never receives a PUT request. When I refresh the page I go back to the old state of the model..
However if I dont clone the array and change the function to, this:
addpeople :function(){
var authArray = this.model.get("authorizedUsers");
var values = $(".add-input").val().split(",");
values.forEach(function(value) {
authArray.push(value);
});
this.model.set("authorizedUsers" , authArray);
this.model.save();
},
This time the PUT request is sent successfully, but the page is not re-rendered because a change event is not triggered. When I refresh the page I can see the updated model..
I know that I can manually trigger a change event in the second example but I am more curious about why my this.model.save()
is not called in the first example..
To help you understand the problem more my model looks something like:
var PostModel = Backbone.Model.extend({
urlRoot : '/tweet',
idAttribute: '_id',
defaults:{
name: '',
comments: [],
tags: [],
authorizedUsers: [],
postedBy : '',
dateCreated: ''
},
});
and my node.js update function looks like:
exports.updateTweet = function(req,res){
console.log("Getting called ! ")
var update = req.body;
var id = req.url.split("/")[2];
Post.update({ _id: id }, { $set: { authorizedUsers: req.body.authorizedUsers }}, function (err, post) {
if (err) return handleError(err);
});
res.end();
};
回答1:
The reason why change
didn't trigger for your second example is because it is the same object and Backbone
ignore it. Hence no change
event triggered.
As for why the first one failed; do you have validator for your model? May be something that validating for empty string perhaps? val()
can return an empty string and split()
on empty string will return [""]
Also, your defaults should be a function otherwise all your model would have the same instance of comments
, tags
and authorizedUsers
From Backbone doc.
Remember that in JavaScript, objects are passed by reference, so if you include an object as a default value, it will be shared among all instances. Instead, define defaults as a function.
Arrays are object too.
var PostModel = Backbone.Model.extend({
urlRoot : '/tweet',
idAttribute: '_id',
defaults: function(){
return {
name: '',
comments: [],
tags: [],
authorizedUsers: [],
postedBy : '',
dateCreated: ''
}
}
});
Lastly, array.forEach()
is not available on IE8 and older.
来源:https://stackoverflow.com/questions/18117349/backbone-not-making-a-put-request-with-save-after-save