LoginSignup
7
2
お題は不問!Qiita Engineer Festa 2023で記事投稿!

Phoenix1.7 自作した関数コンポーネントを<.関数名>で呼び出す

Last updated at Posted at 2023-06-24

こんにちは!
プログラミング未経験文系出身、Elixirの国に迷い込んだ?!見習いアルケミストのaliceと申します。
今回はform_components.exから自作の関数コンポーネント1を呼び出すときに <.関数名>で呼び出す方法を学びました。

■「Phoenix1.7 関数コンポーネントで遊んでみる」シリーズの目次
モーダル上に文字数制限無しのtextareaを作成する
|> ②Phoenix.Component.attr/3 を使って関数コンポーネントを作る
|> ③core_components.exの外に関数コンポーネントを作る
|> ④自作した関数コンポーネントを<.関数名>で呼び出す

目的

前回は自作の関数コンポーネントmy_components.exを作りました。
しかし、使用する際にモジュール名を指定しないと呼び出せない状態になっています。

form_components.ex
<Mycomponents.input field={@form[:message]} type="textarea" label="Message" />

そこで、以下のように、<.関数名>で呼び出して、見やすいコードにしたい。

form_components.ex
<.input field={@form[:message]} type="textarea" label="Message" />

前回の記事はこちら

実行環境

Windows 11 + WSL2 + Ubuntu 22.04
Elixir v1.14.3
Phoenix v1.7.3

仮説

  • my_components.ex
    └関数名がinputのままだとCoreComponents.input/1と干渉してしまうので、Mycomponents.input/1の関数名を変更するのではないか?

  • contact_web.ex
    html_helpersimport ContactWeb.Mycomponentsと書き込むのではないか?2

結果

仮説通りでした。以下のように実施して目的を達成しました。

1. Mycomponents.input/1の関数名を変更する

関数名がinputのままだとCoreComponents.input/1と干渉してしまうので、Mycomponents.input/1の関数名を変更します。

my_components.ex
-  def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
+  def textarea(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
     assigns
     |> assign(field: nil, id: assigns.id || field.id)
     |> assign(:errors, Enum.map(field.errors, &CoreComponents.translate_error(&1)))
     |> assign_new(:name, fn -> if assigns.multiple, do: field.name <> "[]", else: field.name end)
     |> assign_new(:value, fn -> field.value end)
-    |> Mycomponents.input()
+    |> Mycomponents.textarea()
  end
my_components.ex
-  def input(%{type: "textarea"} = assigns) do
+  def textarea(%{type: "textarea"} = assigns) do
    ~H"""
    <div phx-feedback-for={@name}>
      <CoreComponents.label for={@id}><%= @label %></CoreComponents.label>
      <textarea
        id={@id}
        name={@name}
        rows={@rows}
        class={[
          "mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6",
          "phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400 bg-green-500/50",
          @errors == [] && "border-zinc-300 focus:border-zinc-400",
          @errors != [] && "border-rose-400 focus:border-rose-400"
        ]}
        {@rest}
      ><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
      <CoreComponents.error :for={msg <- @errors}><%= msg %></CoreComponents.error>
    </div>
    """
  end

2. html_helpersに自作した関数コンポーネントのimport文を書き込む

contact_web.ex
   defp html_helpers do
       quote do
         # HTML escaping functionality
         import Phoenix.HTML
         # Core UI components and translation
         import ContactWeb.CoreComponents
         import ContactWeb.Gettext
+        import ContactWeb.Mycomponents

         # Shortcut for generating JS commands
         alias Phoenix.LiveView.JS

         # Routes generation with the ~p sigil
         unquote(verified_routes())
       end
     end

3. <.関数名>で呼び出す

form_components.ex
- <Mycomponents.input field={@form[:message]} type="textarea" label="Message" />
+ <.textarea field={@form[:message]} type="textarea" label="Message" />

できました(^▽^)/

<.関数名>で自作の関数コンポーネントを呼び出せています。
image.png

~Elixirの国のご案内~

↓Elixirって何ぞや?と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ!私もエンジニア未経験から学習中です。

We Are The Alchemists, my friends!:bouquet:3
Elixirコミュニティは本当に優しくて温かい人たちばかり!
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。4

  1. 背景色がbg-green-500/50のtextareaをrenderする関数です。

  2. その仮説を考えた理由は、html_helpersに記載すると、全てのHTMLビューにおいてmy_components.exがimportされるので、何度もimport文を書かなくていいのでは?と考えたからです。 https://zenn.dev/koga1020/books/phoenix-guide-ja-1-7/viewer/components#%E3%82%B3%E3%82%A2%E3%82%B3%E3%83%B3%E3%82%BB%E3%83%97%E3%83%88

  3. @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。

  4. @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中!

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2