方法可以?在javascript文件中

时间:2015-10-29 06:54:59

标签: ruby-on-rails cancan

尝试调用方法时出错了吗?

  

未定义的方法`可以吗?'对于#<#:0xa9a6d0e8>

spr_well_types.js.erb文件:

    <% if can? :buttoncreate, SprWellType %>
        container.append('<div style="margin-left: 5px; float: left;" id="spr_well_type_addrowbutton"><span class="glyphicon glyphicon-plus"></span>Add</div>');
    <% end %>

application.html.erb文件:

<%= stylesheet_link_tag "application", params[:controller], :media => "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", params[:controller], "data-turbolinks-track" => true %>

assets.rb文件:

%w( home
    spr_well_types
    spr_well_purposes 
    spr_well_constructions 
    spr_prod_programs
    spr_well_constr_details
    carpets
    spr_minefields
    spr_org_structures
    spr_layers
    mwp_plan_drillings
    planing_drill_wells
    spr_drill_rig_types
    schedules
    devise/sessions
    devise/registrations
    permissions
     ).each do |controller|
      Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
    end

2 个答案:

答案 0 :(得分:2)

如果spr_well_types.js.erb位于您的资产管道(IE /app/assets/javascripts/...)中,您会发现您不能在其中使用任何面向对象的方法。

Martin M所述,这是因为 assets 是静态的(CSS / JS)。它们可以是precompiled,因此它们在生产中具有较小的文件大小(minified)。

使用路径和其他帮助是可以接受的(这些不会改变),但尝试使用can?之类的方法根本不起作用(他们依靠动态数据)。

简单的解释是JS是客户端,而Rails是服务器端。 JS无法访问与Rails相同的数据,因此无法在不存在的数据上运行方法。

<强>视图

如果您想使用此类功能,则必须将其放在 views 目录中,并通过控制器操作调用它。

此服务器端javascript未预编译, 可以访问与Rails相同的数据。因此,在ERB的帮助下,您可以使用所需的面向对象方法。

你没有给我足够的背景知道你如何调用文件,但这是你可以做的一个例子:

#app/controllers/spr_well_types_controller.rb
class SprWellTypesController < ApplicationController
   def show
     # your code here
     respond_to do |format|
       format.js #-> app/views/spr_well_types/show.js.erb
     end
   end
end

#app/views/spr_well_types/show.js.erb
<% if can? :buttoncreate, SprWellType %>
    container.append('<div style="margin-left: 5px; float: left;" id="spr_well_type_addrowbutton"><span class="glyphicon glyphicon-plus"></span>Add</div>');
<% end %>

必须注意respond_to接受请求mime类型,这意味着如果您要同时处理htmljs个响应,则必须使用他们的请求发送不同的请求各自的方法。如果需要,我可以解释一下。

答案 1 :(得分:1)

由于资产是预编译的,因此他们无法了解请求和会话 您必须通过具有此知识的程序部分(即视图)提供此数据。

我通常将这种信息设置为我的布局中的全局DOM变量或数据属性(或者我在所有布局中插入的共享视图),并在我预编译的JS中使用此全局数据。

对预编译的JS文件(if context.nextFocusedView == accountAddOkButton { context.nextFocusedView!.transform = CGAffineTransformMakeScale(1.1, 1.1) let layer = context.nextFocusedView!.layer layer.shadowOffset = CGSizeMake(1, 1) layer.shadowColor = UIColor.blackColor().CGColor layer.shadowRadius = 12.0 layer.shadowOpacity = 0.80 layer.shadowPath = UIBezierPath(rect: layer.bounds).CGPath } )的Ruby处理用于在编译时计算资产路径。