Backbone.Model.save 没有使用服务器响应设置我的模型
我在模型上调用“保存”,并在 PHP 后端以 json 形式返回新模型。当我单步执行 Backbone.Model.save 方法时,我可以看到它成功获取服务器响应,然后设置模型(在下面的 options.success 闭包中)。但是当执行返回到我的点击处理程序时,模型具有旧属性(即未设置 id)。可能会发生什么?
这是我的点击处理程序:
addButtonClick: function(e) {
var data = $(e.target).closest('form').serializeObject();
var p = new Domain.Page; // this extends Backbone.Model
p.set(data);
p.save();
// ****
// **** AFTER p.save, the model p still has the OLD ATTRIBUTES... why??
// ****
return false;
}
这是 Backbone 的保存方法:
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save : function(attrs, options) {
options || (options = {});
if (attrs && !this.set(attrs, options)) return false;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
// ****
// **** NEXT LINE SUCCESSFULLY SETS THE MODEL WITH THE SERVER RESPONSE
// ****
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp, xhr);
};
options.error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update';
return (this.sync || Backbone.sync).call(this, method, this, options);
},
I'm calling 'save' on my model and returning the new model as json in my PHP backend. When I step through the Backbone.Model.save method, I can see that it successfully gets the server response and then sets the model (in the options.success closure below). But when the execution is returned to my click handler, the model has the old properties (ie. the id is not set). What could be happening?
Here is my click handler:
addButtonClick: function(e) {
var data = $(e.target).closest('form').serializeObject();
var p = new Domain.Page; // this extends Backbone.Model
p.set(data);
p.save();
// ****
// **** AFTER p.save, the model p still has the OLD ATTRIBUTES... why??
// ****
return false;
}
Here is Backbone's save method:
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save : function(attrs, options) {
options || (options = {});
if (attrs && !this.set(attrs, options)) return false;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
// ****
// **** NEXT LINE SUCCESSFULLY SETS THE MODEL WITH THE SERVER RESPONSE
// ****
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp, xhr);
};
options.error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update';
return (this.sync || Backbone.sync).call(this, method, this, options);
},
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
save
方法是异步的。换句话说,save
中的model.set
调用发生在服务器响应之后。您问为什么在调用
save
后值立即相同。答案是:此时,您的代码尚未收到响应。回调尚未被调用。model.set
尚未被调用。当您继续并且事件循环从服务器获取响应(这可能是几分之一秒,也可能是几秒钟)之后,您的值将被设置。
The
save
method is asynchronous. In other words, themodel.set
call insidesave
happens after the server has responded.You are asking why the values are the same immediately after
save
is called. The answer is: at that point in time, the response has not been received by your code yet. The callback hasn't been called.model.set
hasn't been called.When you continue on and the event loop gets the response from the server (this may be a fraction of a second, it may be several seconds) later, your values will get set.
我想我知道这里出了什么问题。 Brian 你说得对,这与 Backbone.save 调用的异步性质有关。问题是我正在使用调试器。这将停止所有执行。我实际上不太明白异步调用在幕后是如何工作的,也许是通过线程?我假设在我跳过对“保存”的调用然后等待一秒钟后,“保存”调用的异步部分(无论是什么)将在后台执行。但事实并非如此。调试器停止一切。因此,在跳过“save”之后,“save”中的 options.success 闭包总是会被调用。简而言之,这整件事是因为我没有正确理解 javascript 和 javascript 调试。
I think I figured out what was wrong here. And Brian you were right to say it had something to do with the async nature of the Backbone.save call. The thing is that I was using the DEBUGGER. This stops all execution. I actually don't really understand how an async call works under the hood, perhaps with threads? I assumed that after I stepped over the call to 'save' and then waited a sec, then the async part (whatever that is) of the 'save' call would execute in the background. But this is not the case. The debugger halts everything. So the options.success closure within 'save' always gets called sometime after stepping over 'save'. In short, this whole thing is due to me not understanding javascript and javascript debugging properly.