【发布时间】:2020-02-07 21:43:09
【问题描述】:
我有一个表单可以在sources#create 上创建一个新的source,上面有一个模式可以创建一个新的author。用户可以创建一个新的author 以分配给源,也可以从清单中选择一个现有的。
理想情况下,如果他们确实需要创建新作者,authors#create 表单会以 AJAX 方式创建作者,并且新作者将自动出现在可与源相关联的作者清单中。
这是sources#create上的作者选择复选框的代码:
<section id="author" class="white h-100">
<h2>Author(s)</h2>
<% if @user_authors.count != 0 %>
<p class="text-center">Select an author to add below or <a data-toggle="modal" data-target="#newAuthorModal">create a new author</a>.</p>
<div id="#authorsChecklist"><%= render partial: "authors/checklist", locals: { f: f } %></div>
<% else %>
<p class="text-center"><a data-toggle="modal" data-target="#newAuthorModal">Create a New Author</a></p>
<% end %>
</section>
以此为authors/_checklist.html.erb 部分:
<div class="boxed-scroll">
<%= f.collection_check_boxes :author_ids, @user_authors.sort_by(&:last_name), :id, :last_first do |b| %>
<div class="field form-check" style="display: block">
<%= b.check_box class: "form-check-input" %>
<%= b.label class: "form-check-label" %>
</div>
<% end %>
</div> <!-- boxedscroll -->
这是创建作者的模态:
<!-- New Author Modal -->
<div class="modal fade" id="newAuthorModal" tabindex="-1" role="dialog" aria-labelledby="newAuthorModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newAuthorModalLabel">Add a New Author</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<%= render partial: "authors/js_form", locals: {author: @new_author} %>
</div>
</div>
</div>
</div>
这是create 方法:
def create
@author = Author.new(author_params)
@author.user_id = current_user.id
respond_to do |format|
if @author.save
format.html { redirect_back(fallback_location: author_path(@author)) }
format.json { render :show, status: :created, location: @author }
format.js
else
format.html { render :new }
format.json { render json: @author.errors, status: :unprocessable_entity }
end
end
end
这里是authors/create.js:
$("#authorsChecklist").html("<%= escape_javascript(render partial: 'authors/checklist', locals: { f: f } ) %>");
到目前为止,作者确实创建成功:
Started POST "/authors" for ::1 at 2020-01-31 21:23:26 -0800
Processing by AuthorsController#create as JS
Parameters: {"utf8"=>"✓", "author"=>{"first_name"=>"Liz", "middle_initials"=>"", "last_name"=>"Bayardelle", "notes"=>""}, "commit"=>"Save Author Info"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:5
(0.1ms) BEGIN
↳ app/controllers/authors_controller.rb:32
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/authors_controller.rb:32
Author Create (0.8ms) INSERT INTO "authors" ("first_name", "middle_initials", "last_name", "notes", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["first_name", "Liz"], ["middle_initials", ""], ["last_name", "Bayardelle"], ["notes", ""], ["user_id", 1], ["created_at", "2020-02-01 05:23:26.279449"], ["updated_at", "2020-02-01 05:23:26.279449"]]
↳ app/controllers/authors_controller.rb:32
(0.4ms) COMMIT
↳ app/controllers/authors_controller.rb:32
Rendering authors/create.js
Rendered authors/create.js (0.4ms)
Completed 200 OK in 214ms (Views: 27.8ms | ActiveRecord: 42.7ms)
但是,当您点击提交并且作者没有被添加到复选框列表时,模式不会消失(基本上部分不会刷新)。当您手动点击刷新时,作者会完美显示。
任何人都可以看到如何正确地将其传输到 AJAX 吗?期望的行为是当您点击提交时模态框消失,并且清单部分为 AJAX-ically 刷新以便作者出现。
更新
根据评论建议,我将这个添加到create.js,成功使模态消失,虽然部分没有刷新:
$('#newAuthorModal').modal('hide');
然后我找到了this question,这表明我需要将create.js 更改为create.js.erb。这以某种方式阻止了模式消失,但产生了一个服务器错误:
NameError - undefined local variable or method `f' for #<#<Class:0x00007f9e1e0c0ad0>:0x00007f9e18101d38>:
app/views/authors/create.js.erb:2:in `_app_views_authors_create_js_erb__3387754959944580247_70158492637620'
第二次更新
查阅collection_check_boxes 的文档后,collection_check_boxes 之前的f. 不是必需的。我删除了它并从我的create.js.erb 中删除了, locals: { f: f }。模态现在正确关闭并且错误消失了,但我仍然必须点击刷新才能显示名称。
【问题讨论】:
-
$('#modal').modal('hide');你能把这个添加到“create.js”中吗 -
我看不到您实际上在任何地方都有表格。
authors/create.js中的局部变量f来自哪里?为什么这不会引发 NoMethodError?是不是很简单,比如忘记保存文件或文件路径/名称错误? -
@7urkm3n 我添加了
$('#newAuthorModal').modal('hide');,它现在确实成功地关闭了模式。谢谢!现在我们至少知道它击中了create.js。但是,我仍然需要点击刷新才能让新作者出现在列表中。 -
@Liz 看起来你的结构很糟糕,我也不明白这里的意思。
-
当您从
create.js.erb渲染您的部分时,您并没有在初始表单渲染的上下文中执行它...即,f不存在...您将需要考虑改用 check_box_tags。
标签: ruby-on-rails ajax