1

我想在 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 with {: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 渲染和/或重定向在此操作中被多次调用。请注意,您只能调用渲染或重定向,每个操作最多调用一次。另请注意,既不重定向也不渲染终止动作的执行,所以如果你想在重定向后退出动作,你需要做一些类似“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 %>

我该如何解决?提前致谢

4

2 回答 2

1

#render_wizard中定义的方法是该方法Wicked::Controller::Concerns::RenderRedirect的包装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模板而不是模板,请尝试向render_wizard 方法.js.erb添加一个选项。formats: 'js'它应该将 ['js'] 添加到:formats=>[:html]我们在Missing template错误消息中看到的前面。

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
于 2016-09-07T12:40:00.040 回答
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

于 2016-09-07T16:23:52.070 回答