我试图在点击更新端点后显示flash消息。我想让用户保持在同一页面并告诉他信息已更新。我启用了turbolink。
以下是我的行动:
def update
@form = Form.find(params[:id])
if @form.update(form_params)
respond_to do |format|
flash.now[:notice] = "Form updated successfully"
format.html { render 'edit' }
format.js { render 'edit' }
# format.html { redirect_to edit_form_path(@form), notice: "Form updated successfully" }
format.json { render json: {message: "Form updated successfully", form: @form} }
end
else
respond_to do |format|
format.html { render 'new'}
format.json { render json: {errors: @form.errors}, status: :unprocessable_entity }
end
end
end
我已经尝试了flash
和flash.now
都没有产生结果。如果您看到注释掉的行将重定向到同一页面并渲染闪光灯。
这是我打印falsh的方式:
<%= notice %>
<%= flash.notice %>
我已经使用过它们,但似乎没有用。
根据我的观察,我可以看到Turbolinks击中format.js
端点。任何人都可以帮我这个吗?
修改
这就是我的表单的样子:
<%= form_with(model: @form, method: 'put') do |f| %>
<!-- name -->
<div class="field">
<label class="label">
From Name
<sup class="is-danger">*</sup>
</label>
<p class="control">
<%= f.text_field :name, class: "input" %>
</p>
<% if @form.errors.any? %>
<p class="help is-danger">
Form name <%= @form.errors[:name].first %>
</p>
<% end %>
</div>
<!-- create button -->
<div class="control">
<%= f.submit class: "button is-primary" %>
</div>
<% end %>
答案 0 :(得分:1)
要表示您想通过Ajax提交表单,您需要将remote: true
放在表单元素上,如下所示:
<%= form_with model: @form, method: 'put', remote: true do |f| %>
<!-- rest of the form -->
<% end %>
当您点击提交时,您会注意到该页面没有更改,但您的Rails日志仍然显示您已ping通您的控制器。整齐!
接下来,您需要弄清楚如何处理这些数据。这是respond_to
的用途。
respond_to
将根据控制器的访问方式发送不同的响应。在您的情况下,重要的是format.js
,但您始终希望为HTML提供后备。
def update
@form = Form.find(params[:id])
if @form.update form_params
respond_to do |format|
flash.now[:notice] = "Form updated successfully"
format.html { redirect_to <SHOW PATH> }
format.js # Will automatically look for update.js.erb
format.json { render json: {message: "Form updated successfully", form: @form} }
end
else
respond_to do |format|
format.html { render :edit }
format.json { render json: {errors: @form.errors}, status: :unprocessable_entity }
end
end
end
end
请注意,我做了一些代码更改。
现在,当您提交表单时,您应该看到没有任何更改,控制器被命中,处理记录,然后Rails将查找update.js.erb
。这就是我们下一步要去的地方!
创建该文件后,请填写:
console.log("<%= notice %>");
此时,确认您在提交后可以在控制台中看到闪光灯。
您需要将显示您的Flash消息的HTML抽象为我打算调用_notifications.html.erb
的部分内容,并且它将包含以下内容:
<!-- _notifications.html.erb -->
<div id="flash">
<% if notice.present? %>
<%= notice %>
<% end %>
</div>
最后,您必须更换闪光灯的内容。从update.js.erb
删除所有内容并尝试此操作:
$('#flash').replaceWith("<%= j(render 'notifications') %>");
// Or
var flash = document.getElementById('flash'),
flashParent = flash.parentNode;
flashParent.replaceChild("<%= j(render 'notifications') %>", flash);
那就是它!试一试,让我知道它是否有效。
答案 1 :(得分:0)
如果Ajax方法存在太大问题,请删除remote: true
并尝试:
def update
@form = Form.find(params[:id])
if @form.update form_params
respond_to do |format|
format.html { redirect_to <EDIT PATH>, notice: "Form updated successfully" }
format.json { render json: {message: "Form updated successfully", form: @form} }
end
else
respond_to do |format|
format.html { render :edit }
format.json { render json: {errors: @form.errors}, status: :unprocessable_entity }
end
end
end
end
然后你应该在页面上有flash数据。尝试使用<%= flash.inspect %>
进行验证。 Turbolinks应该在这里处理大部分魔术。
缺点是Turbolinks可以在移动设备上给你一些问题。如果你尝试这种方法,我建议调查一下。
就个人而言,我更喜欢Ajax方法。它的工作量稍微多一点,但它可以让你获得更细粒度的控制。