【问题标题】:Rails wicked wizard with javascript带有 javascript 的 Rails 邪恶向导
【发布时间】:2017-01-15 00:45:21
【问题描述】:

我想在js中创建一个向导。

steps   :first_step,
        :second_step

在我的“controller_step”中

def show
        case step
            when :first_step
                @r  = R.new
            when :second_step

            end
        render_wizard
end

def update
        case step
            when :first_step
                @r = R.new(r_params)
            when :second_step

            end

        render_wizard @r
end

第一步更新后出现问题。我收到以下错误消息:

“缺少模板controller_step/second_step, application/second_step 使用 {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}。 ”。

如何强制加载 js 模板?我会加载“second_step.js.erb”。

我尝试改变更新方式:

respond_to do |format|
  format.js { render :js => ( render_wizard @r ) }  
end

当然我得到以下错误:

"AbstractController::DoubleRenderError in ...Controller#update Render 和/或重定向在此操作中被多次调用。请注意 您只能调用渲染或重定向,并且每次最多调用一次 行动。另请注意,重定向和渲染都不会终止执行 的动作,所以如果你想在重定向后退出一个动作,你 需要做一些类似“redirect_to(...) and return”的事情。”

我也尝试更改代码(更新中):

respond_to do |format|
   format.js { render :js => ( render_wizard @room_types and return ) } 
end

我遇到了同样的错误(... application/second_step with {:locale=>[:en], :formats=>[:html] ....)

附言

鉴于第一步:

<%= form_for(@r, url: wizard_path, method: :put, remote: true) do |f| %>
   ....
   <%= f.submit "Submit", class: "btn btn-default" %>
<% end %>

我该如何解决?提前致谢

【问题讨论】:

    标签: javascript ruby-on-rails bootstrap-modal multi-step wicked-gem


    【解决方案1】:

    我是这样解决的:

    在 r 模型中:

    validates   :x, presence: true
    

    在步进控制器中:

    ...
    steps   :first_step,
            :second_step,
            :finish_step
    ...
    
    def show
        case step
            when :first_step
                @room_types  = R.new
            end
    
        render_wizard       
    end
    
    def update
       case step
          when :view_new_room_type_step
             @r = R.create(r_params)
          when :view_desc_step
             @r = R.find(params[:r][:id])
             @r.update(r_params)
          end
    
        respond_to do |format|
           if !@r.errors.any?
              format.js { !next_step?(:finish_step) ? ( render next_wizard_path ) : ( redirect_to_finish_wizard ) }
           else
              format.js { render wizard_path, r: @r }
           end
        end
    end 
    
    private
            ...
    
            def redirect_to_finish_wizard
                redirect_to r_index_path , notice: "Ok"
            end
    

    在 first_step.js.erb 中

    $("#modal").html("<%= escape_javascript(render 'form_first_step') %>")
    

    在_form_first_step.html.erb:

    <% if @r.errors.any? %>
       <div class="alert fade in alert-danger alert-dismissable"><button aria-hidden="true" class="close" data-dismiss="alert" type="button">&#215;</button>
          <ul>
             <% @r.errors.full_messages.each do |msg| %>
                <%= content_tag :li, msg, :id => "error_#{msg}" if msg.is_a?(String) %>
              <% end %>
          </ul>
        </div>
    <% end %>
    
    <%= form_for(@room_types, url: wizard_path, method: :put, remote: true) do |f| %>
       ...
    <% end %>
    

    第二种形式(第二步):

    <%= form_for(@room_types, url: wizard_path(:second_step), method: :put, remote: true) do |f| %>
        ....
        <%= f.hidden_field :id %>
    <% end %>
    

    想法:验证步骤中的数据可以使用jquery-form-validator-rails

    【讨论】:

      【解决方案2】:

      Wicked::Controller::Concerns::RenderRedirect 中定义的#render_wizard 方法是ActionController::Base#render 方法的包装方法。它 接受选项哈希并将其传递给控制器​​的常规 #render 方法。

      这是来自 Wicked 库的源代码:

      def render_wizard(resource = nil, options = {})
        ...
      
        if @skip_to
          ...
        else
          render_step wizard_value(step), options
        end
      end
      
      def render_step(the_step, options = {})
        if the_step.nil? || the_step.to_s == Wicked::FINISH_STEP
          ...
        else
          render the_step, options #<-- Here
        end
      end
      

      您的代码:

      respond_to do |format|
        format.js { render :js => ( render_wizard @r ) }  
      end
      

      基本上是在做:

      respond_to do |format|
        format.js { render :js => ( render @r ) }  
      end
      

      实际上是调用了两次渲染方法。

      由于它正在搜索 .html 模板而不是 .js.erb 模板,请尝试在 render_wizard 方法中添加 formats: 'js' 选项。它应该将 ['js'] 添加到我们在Missing template 错误消息中看到的:formats=&gt;[:html]

      respond_to do |format|
        format.js { render_wizard(@r, formats: 'js') }
      end
      

      另外,请确保模板的文件名遵循 Rails 约定并以 _ 开头。 (即:_second_step.js.erb


      关于双重渲染错误,你是对的。您必须从控制器#show#update 方法返回,并防止进一步的代码再次调用#render 方法。你似乎已经解决了这个问题。

      编辑#1

      您似乎可以直接在控制器中调用此方法..:

      def render_step(the_step, options = {})
        # Wicked::FINISH_STEP = "wicked_finish"
        if the_step.nil? || the_step.to_s == Wicked::FINISH_STEP
          redirect_to_finish_wizard options
        else
          render the_step, options
        end
      end
      

      我相信the_step 将是部分的名称。我认为您应该能够从您的控制器调用#render_step 方法。

      你可以这样做:

      def show
        respond_to do |f|
          f.js do
            case step
            when :first_step
                @r  = R.new
                render_step(step) and return
            when :second_step
              ...
            end
          end
        end
      end
      

      【讨论】:

      • 您错过了 render_redirect.rb 中的关键步骤:def render_wizard(resource = nil, options = {}) process_resource!(resource) .... 将参数传递给方法 render_wizard 时,执行 process_resource ... def process_resource!(resource) if resource if resource.save @skip_to ||= @next_step ... 在这种情况下'如果 render_wizard 中的 @skip_to' 为真 .... 并执行 'redirect_to wizard_path(@skip_to, @wicked_redirect_params || {}), options' ...
      • 我听从了你的建议,但它继续给出同样的错误。将参数传递给 render_wizard 时执行的步骤是:render_step wizard_value(step), options(在 render_redirect.rb 中),因为 @skip_to 为 true
      • 你去。通过传递资源,您将被重定向到资源的路径!我应该抓住它。找到解决方案后告诉我!看来您必须绕过#render_wizard 方法并使用#render 方法,以便您可以指定部分..
      • 好的。如果我在渲染第二步时执行render :second_step, :formats =&gt; 'js',我会得到:&lt;form .. action="../first_step" accept-charset="UTF-8" data-remote="true" ...&gt;。向导停留在第一步……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多