如何在 javascript 回调中访问更新的对象(而不是旧对象)
How to access the updated object in a javascript callback (instead of the old object)
基于 提供的有用且有效的解决方案,我也在尝试修复我的更新回调。
问题是,我试图从中提取数据的特定 unit
始终是旧的缓存版本,即使此回调是由成功的 update
操作触发的。
// callback triggered by the update action
$('.best_in_place').bind("ajax:success", function () {
...
console.log(unit.duration);
// which is exactly the same as
console.log(<%= Unit.find(unit.id).unit_users.pluck(:duration).sum %>);
// and both print the OLD duration val instead of the updated val which is in the database
});
和 unit_users_controller 代码...
def update
@unit = @unituser.unit
respond_to do |format|
if @unituser.update(unit_user_params)
@unit.reload
logger.info('-----------------------------------------------------------------')
logger.info('@unit.duration in the controller is ' + @unit.duration.to_s) # which is the correct value
logger.info('-----------------------------------------------------------------')
gon.unit_duration = @unit.duration # an experiment which didn't work for me
format.json {respond_with_bip(@unituser) }
else
# format.html { render :action => 'edit' }
format.json { respond_with_bip(@unituser) }
end
end
end
我试过几个版本的 unit.reload
,但没有任何帮助。也许我放错地方了?
这与缓存无关。您的 Ruby 代码在 服务器 端被评估,在 JavaScript 被发送到客户端之前,它只被评估一次,远在 AJAX 请求可能发生。
客户永远不会看到这一行:
console.log(<%= Unit.find(unit.id).unit_users.pluck(:duration).sum %>);
客户将看到的内容如下:
console.log(32); // or whatever the sum is
此处不能使用<%= %>
。这将始终为您提供原始价值。相反,您需要将新值发送给客户端以响应 AJAX 请求。
我之前做过这个,这是我的代码,也许它会对你有所帮助:
Javascript:
$(document).ready(function() {
$('.price_bind').bind("ajax:success", function (event, data, status, xhr) {
var parsed_data = jQuery.parseJSON(data);
$(this).text(parsed_data.newprice);
$(this).parentsUntil('body').find(".totalpricep span").text(parsed_data.totalprice);
});
}
查看:
<%= best_in_place detail, :price, :classes => 'price_bind', :path => purchase_detail_path(@purchase, detail)%>
控制器:
def update
respond_to do |format|
if @detail.update_attributes(params[:detail])
@n=@detail.mk_bal
@r=false
if @detail.purchase != nil
@p=@detail.purchase.totalprice
if params[:detail]['status'] && @purchase.step==1
@remdet = @purchase.details.where(:step => 1, :status => false)
if @remdet.empty?
@purchase.update_attribute(:step, 2)
@r=true
end
end
else
@p=nil
end
format.html { redirect_to @detail, notice: 'Detail was successfully updated.' }
format.json { render :json => {:newprice => @n, :totalprice => @p, :newstatus => @detail.status, :refresh => @r}}
else
format.html { render action: "edit" }
format.json { render json: @detail.errors, status: :unprocessable_entity }
end
end
end
基于
问题是,我试图从中提取数据的特定 unit
始终是旧的缓存版本,即使此回调是由成功的 update
操作触发的。
// callback triggered by the update action
$('.best_in_place').bind("ajax:success", function () {
...
console.log(unit.duration);
// which is exactly the same as
console.log(<%= Unit.find(unit.id).unit_users.pluck(:duration).sum %>);
// and both print the OLD duration val instead of the updated val which is in the database
});
和 unit_users_controller 代码...
def update
@unit = @unituser.unit
respond_to do |format|
if @unituser.update(unit_user_params)
@unit.reload
logger.info('-----------------------------------------------------------------')
logger.info('@unit.duration in the controller is ' + @unit.duration.to_s) # which is the correct value
logger.info('-----------------------------------------------------------------')
gon.unit_duration = @unit.duration # an experiment which didn't work for me
format.json {respond_with_bip(@unituser) }
else
# format.html { render :action => 'edit' }
format.json { respond_with_bip(@unituser) }
end
end
end
我试过几个版本的 unit.reload
,但没有任何帮助。也许我放错地方了?
这与缓存无关。您的 Ruby 代码在 服务器 端被评估,在 JavaScript 被发送到客户端之前,它只被评估一次,远在 AJAX 请求可能发生。
客户永远不会看到这一行:
console.log(<%= Unit.find(unit.id).unit_users.pluck(:duration).sum %>);
客户将看到的内容如下:
console.log(32); // or whatever the sum is
此处不能使用<%= %>
。这将始终为您提供原始价值。相反,您需要将新值发送给客户端以响应 AJAX 请求。
我之前做过这个,这是我的代码,也许它会对你有所帮助:
Javascript:
$(document).ready(function() {
$('.price_bind').bind("ajax:success", function (event, data, status, xhr) {
var parsed_data = jQuery.parseJSON(data);
$(this).text(parsed_data.newprice);
$(this).parentsUntil('body').find(".totalpricep span").text(parsed_data.totalprice);
});
}
查看:
<%= best_in_place detail, :price, :classes => 'price_bind', :path => purchase_detail_path(@purchase, detail)%>
控制器:
def update
respond_to do |format|
if @detail.update_attributes(params[:detail])
@n=@detail.mk_bal
@r=false
if @detail.purchase != nil
@p=@detail.purchase.totalprice
if params[:detail]['status'] && @purchase.step==1
@remdet = @purchase.details.where(:step => 1, :status => false)
if @remdet.empty?
@purchase.update_attribute(:step, 2)
@r=true
end
end
else
@p=nil
end
format.html { redirect_to @detail, notice: 'Detail was successfully updated.' }
format.json { render :json => {:newprice => @n, :totalprice => @p, :newstatus => @detail.status, :refresh => @r}}
else
format.html { render action: "edit" }
format.json { render json: @detail.errors, status: :unprocessable_entity }
end
end
end