【问题标题】:Dynamic Select Menu Rails 4动态选择菜单 Rails 4
【发布时间】:2016-02-09 00:54:34
【问题描述】:

我正在尝试使用此guide 制作动态选择菜单;但是,它似乎并没有改变 select select 语句。

这是我所拥有的代码:

#characters_controller.rb
    def new
        @skills = Skill.all
        @classes = Classe.all
        @background = Background.all
        @character = Character.new
    end
    def update_classe_skills
        classe = Classe.find(params[:character][:classe_id])

        @skills = classe.skills.map{|a| [a.name,a.name]}.insert(0,"Select a Skill")
        respond_to do |format|
            format.js
        end
    end


#routes.rb
Rails.application.routes.draw do
    resources :characters
    get 'characters/update_classe_skills', :as => 'update_classe_skills'
end

这是 .js.erb 文件:

#update_classe_skills.js.erb

$('#character_classe_skill_option_one').html("<%= escape_javascript(options_for_select(@skills)) %>");

这是我的 AJAX 脚本:

#skills_select_handler.js
$(document).ready(function() {
    $(document).on('change','#character_classe_id', function() {
      $.ajax({
        url: "#{update_classe_skills_path}",
        data: {
          classe_id : $('#character_classe_id').val()
        },
        dataType: "script",
        type: 'GET'
      });
    });
 });

最后,这是我的选择菜单:

#new.html.erb
<%= javascript_include_tag "skills_select_handler.js"  %>
<%= form_for :character, url: characters_path, method: :post do |f| %>
    <%= render :partial => "info_step", :locals => {:f => f} %>
    <%= render :partial => "rand_prompt_step", :locals => {:f => f} %>
    <%= render :partial => "skills_step", :locals => {:f => f}%>
<% end %>
#_info_step.html.erb
<p>
    <%= f.label :classe_id, "Class" %><br>
    <%= f.select :classe_id, options_for_select([["Barbarian", 1], ["Bard", 2], ["Cleric", 3], ["Druid", 4], ["Fighter", 5], ["Monk", 6], ["Paladin", 7], ["Ranger", 8], ["Rogue", 9], ["Sorcerer", 10], ["Warlock", 11], ["Wizard", 12]], selected: "#{@character.classe_id}"), include_blank: true, id:'character_classe_id' %>
    <span><%= @character.errors[:classe_id][0] %></span>
</p>

#_skills_step.html.erb
<div id="classe_skill_proficiency_one">
    <p>
        <%= f.label :classe_skill_option_one, "Skill Proficiency" %>
        <br>
        <%= f.collection_select(:classe_skill_option_one, @skills, :name, :name,{:prompt   => "Select a Skill"}, {id: 'character_classe_skill_option_one'})%>
    </p>
</div>

我曾经在“新”视图中渲染所有部分,但是,这不起作用。我已经尝试自己进行故障排除,所以事情可能变得有些不稳定。

当我在更改类后查看服务器控制台时,我确实看到了以下内容:

Processing by CharactersController#new as JS
  Parameters: {"classe_id"=>"1", "_"=>"1454977094482"}
  [list of stuff being loaded and rendered]
  Skill Load (0.0ms)  SELECT "skills".* FROM "skills"

所以这让我相信它领先于 AJAX 请求,但随后只加载整个技能列表,而不是加入特定类的技能。

连接表是正确的,所以这不是问题。

有人对如何让选择菜单更改其选项有任何想法吗?

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax ruby-on-rails-4


    【解决方案1】:

    这样做:

    #config/routes.rb
    resources :characters
      get "update_classe_skills/:classe_id", as: 'update_classe_skills', on: :collection #-> url.com/characters/update_classe_skills/:classe_id
    end
    
    #skills_select_handler.js
    $(document).on("change","#character_classe_id", function(e) {
      var classe_id = $(this).val();
      $.ajax({
         url: "characters/update_classe_skills/" + classe_id,
         data: { classe_id : classe_id },
         dataType: "script",
         type: 'GET'
       });
     });
    
     #app/controllers/characters_controller.rb
     class CharactersController < ApplicationController
    
        def update_classe_skills
          @classe = Classe.find params[:classe_id]
          respond_to do |format|
            format.js
          end          
        end
    
    end
    
    #app/views/characters/update_classe_skills.js.erb
    $('select#character_classe_skill_option_one').empty.append("<%=j options_from_collection_for_select(@skills, 'name', 'name') %>");
    

    我相信您的代码中有几个错误:

    1. 您的ajax URL 依赖于 JS 值 (classe_id),但您没有它
    2. 您的update_classe_skills JS 不会更新select(仅容器div
    3. 您的控制器方法效率低下

    【讨论】:

      【解决方案2】:

      我最终弄明白了。结果是路线问题。

      我更改了以下内容:

      #characters_controller.rb
      def update_classe_skills
          classe = Classe.find(params[:classe_id])
      
          @skills = classe.skills.map{|a| [a.name,a.name]}.insert(0,"Select a Skill")
          respond_to do |format|
              format.js
          end
      end
      
      
      #skills_select_handler.js
      $(document).ready(function() {
          $(document).on('change','#character_classe_id', function() {
            $.ajax({
              url: "/update_classe_skills",
              data: {
                classe_id : $('#character_classe_id').val()
              },
              dataType: "script",
              type: 'GET'
            });
          });
       });
      
      #routes.rb
      Rails.application.routes.draw do
          resources :characters
          match "/update_classe_skills", :to => "characters#update_classe_skills", :via => [:get]
      end
      

      我还必须将protect_from_forgery_except :update_classe_skills 添加到我的角色控制器。

      发生这种情况的原因是因为resources :characters在我的路由中生成了show route。它正在寻找/characters/:id,因此我的路线被处理为显示路线,并且由于没有:id =&gt; "update_classe_skills"而没有得到任何结果

      【讨论】:

        猜你喜欢
        • 2015-03-03
        • 2012-06-16
        • 2012-11-01
        • 1970-01-01
        • 2015-12-28
        • 2016-07-21
        • 2016-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多