我已经被这个问题困扰了几天,但没有找到任何可以帮助我的东西。
这个想法是获取在模式弹出窗口中呈现的 Price_scenarios 索引 View 。对于表中显示的每个 Price_scenario,都会调用 Controller 方法“price”。此方法从模型中获取一些信息并使用 JSON 对其进行格式化。这种获取价格的方法是为不再参与该项目的以前的开发人员编写的,并且是必要的,因为价格值可能需要一段时间才能计算出来,因此在页面加载时会呈现一个小轮子 gif。
问题:price_scenarios“价格”方法不呈现任何值。仅当在模态弹出窗口中渲染的索引 View 中调用“价格”时才会发生这种情况,我已经尝试过渲染价格_场景索引并且效果很好。此外,此方法已成功用于应用程序的许多其他 View 。我认为这一定是格式响应的问题,因为从弹出窗口调用该方法,但我尝试过的所有方法都没有改善结果。
product show.html.haml 一个按钮,以模态弹出窗口的形式显示price_scenarios索引:
%h3
= model_class.human_attribute_name(:price)
= link_to PriceScenario.model_name.human(count: 2), formula_product_price_scenarios_path(@formula, @product), remote: true, data: {toggle: "modal", target: "#price_scenarios"}, class: "btn"
#price_scenarios(class="modal hide fade" role="dialog" aria-labelledby="Delta" aria-hidden="true")
price_scenarios_controller.rb索引和价格方法的定义
class PriceScenariosController < ApplicationController
before_filter :require_client
load_and_authorize_resource :formula
load_and_authorize_resource :product, :through => :formula
before_filter :get_tuple, only: :price
def index
@price_scenarios = @product.price_scenarios
respond_to :js
end
def price
@price_scenario = PriceScenario.find(params[:id])
@price = @price_scenario.shifted_price(@tuple)
@price_units = @product.price_units
respond_to do |format|
format.html { render partial: 'price'}
format.json { render json: {price: @price, units: @price_units}}
end
end
price_scenario index.js.haml View 在模态中呈现索引 View :
$("#price_scenarios").html("#{escape_javascript(render partial: 'modal_price_scenarios')}");
_modal_price_scenarios.html.haml 在模态中呈现的 View ,在其中调用“price”。
#modal_price_scenarios(class="modal" role="dialog" aria-labelledby="Delta" aria-hidden="true")
- model_class = PriceScenario
.modal-body
%table.table.table-striped
%thead
%tr
%th= model_class.model_name.human
%th= model_class.human_attribute_name(:price)
%th= model_class.human_attribute_name(:references)
%tbody
- @price_scenarios.each do |scenario|
%tr
%td= scenario.name
%td.price{:"data-product-price" => price_formula_product_price_scenario_path(@formula, @product, scenario)}
= image_tag('ajax-loader.gif')
-Price.html.haml部分由price_scenarios价格方法呈现。
= "#{@price} #{@price_units}"
product_price.js
$(function(){
$('[data-product-price]').each(function(){
var url = $(this).data('product-price')
$.ajax({
url: url,
cache: false,
dataType: "json"
}).done(function( data ) {
var priceWithUnits = data['price'] + ' ' + data['units']
$('[data-product-price="' + url + '"]').html(priceWithUnits);
});
});
});
浏览器控制台和开发日志没有显示任何错误,但似乎没有执行正确的请求。通过 HttpRequester 启动手动请求会产生正确的结果。
浏览器控制台显示模式后:
GET localhost:3000/es/formulas/84/products/69/price_scenarios [HTTP/1.1 200 OK 1590ms]
POST http://localhost:3000/mini-profiler-resources/results [HTTP/1.1 200 OK 154ms]
开发日志
Rendered price_scenarios/_modal_price_scenarios.html.haml (1537.1ms)
Rendered price_scenarios/index.js.haml (1542.6ms)
手动请求
GET http://localhost:3000/es/formulas/84/products/69/price_scenarios/20/price?_=1427711855278 -- response -- 200 OK
Content-Type: text/html; charset=utf-8 X-UA-Compatible: IE=Edge Cache-Control: must-revalidate, private, max-age=0 X-Request-Id: af912de9ef3e953387ddbd5f687aa1c2 X-Runtime: 2.647176 X-Miniprofiler-Ids: ["yxomxau7wdgouexw439j"] Content-Length: 18 Server: WEBrick/1.3.1 (Ruby/1.9.3/2014-02-24) Date: Mon, 30 Mar 2015 11:04:41 GMT Connection: Keep-Alive 275.391 EUR / MWh
最佳答案
Rendering JSON sets the content type to application/json and optionally wraps the JSON in a callback. It is expected that the response will be parsed (or eval’d) for use as a data structure. http://apidock.com/rails/ActionController/Base/render
但是它实际上并没有将哈希值转换为 JSON 编码的字符串,您需要手动执行此操作:
format.json { render json: {price: @price, units: @price_units}.to_json }
我找到ActiveModel Serializers对于构建 JSON 响应对象非常有用,如果您正在做任何复杂的事情,这些对象很快就会失控。
class PriceSerializer < ActiveModel::Serializer
has_many :price_units
attributes :name, :whatever
end
class PriceScenariosController < ApplicationController
#...
def price
# ...
format.json { render json: @price }
end
end
编辑
另一个问题是,当 product_price.js
时,模态可能实际上并未添加到 DOM 中。已运行。
// Not guaranteed to have run before product_price.js
$("#price_scenarios").html("#{escape_javascript(render partial: 'modal_price_scenarios')}");
可能的解决方案是将部分添加到隐藏元素中,而不是作为 JavaScript 字符串或使用 <template>
元素。
关于javascript - 在模态弹出窗口中调用时,使用 JS 的 Controller 方法不会返回/渲染数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29342273/