问题描述
我正在尝试创建带有地址列表的表单,并允许用户通过Javascript删除或创建新地址。我已将Rails的fields_for与child_index:'new_record'结合使用,以实现类似的功能,其中在通过JavaScript附加表单字段时,我用时间戳替换了new_record字符串(如本Pluralsight教程:https://www.pluralsight.com/guides/ruby-on-rails-nested-attributes所述)。 / p>
我正在寻找的技巧是在Phoenix中具有类似的渲染功能,即如何使用给定的/自定义的子索引生成嵌套表单。目前,我正在努力解决类似问题;
<%= form_for @changeset,Routes.user_path(@conn,:update,@user.id),[data: [controller: "nested-form",action: "nested-form#submit"]],fn f -> %>
<div data-target="nested-form.records">
<%= inputs_for f,:addresses,fn fp -> %>
<%= render __MODULE__,"_address_fields.html",form: fp %>
<% end %>
</div>
<template data-target="nested-form.template">
<%# How do I get a template input group here? %>
<%# In Rails I Could do `f.fields_for :addresses,Address.new,child_index: 'NEW_RECORD'` %>
</template>
<% end %>
但是我不知道如何用Phoenix生成inputs_for
来创建这样的模板。
解决方法
正如@TheAnh所评论,答案在本要点(https://gist.github.com/mjrode/c2939ee7786b157aab131761c8fb89a9)中进行了讨论。为了提供答案,我已经通过以下辅助方法解决了该问题;
defmodule MyAppWeb.UserView do
use MyAppWeb,:view
def template_inputs_for(changeset,field,fun) do
form = Phoenix.HTML.FormData.to_form(changeset,[])
inputs_for(form,fn form ->
id = String.replace(form.id,~r/\d$/,"NEW_RECORD")
name = String.replace(form.name,~r/\[\d\]$/,"[NEW_RECORD]")
fun.(%{form | id: id,name: name})
end)
end
end
然后可以用来生成“模板”字段组;
<%= form_for @changeset,Routes.user_path(@conn,:update,@user.id),[data: [controller: "nested-form",action: "nested-form#submit"]],fn f -> %>
<div data-target="nested-form.records">
<%= inputs_for f,:addresses,fn fp -> %>
<%= render __MODULE__,"_address_fields.html",form: fp %>
<% end %>
</div>
<template data-target="nested-form.template">
<%= template_inputs_for User.changeset(%User{addresses: [%Address{}]}),fn f -> %>
<%= render __MODULE__,form: f %>
<% end %>
</template>
<% end %>