iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Modern Web

速成 Phoenix, 2022年最受喜愛框架系列 第 21

{21, LiveView, "簡單計數器"}

  • 分享至 

  • xImage
  •  

簡單計數器

我們來用一個簡單加減數字的網頁互動計數器來理解 LiveView 的構造

Router

還是要有路徑啦,只是這次路徑指定的目的地不是 controller,而是一個 LiveView 模組

lib/blog_web/router.ex

  scope "/", BlogWeb do
    pipe_through(:browser)
    resources("/notes", NoteController)
    resources("/posts", PostController)
 
    # 使用 live 方法將 "/counter" 指定到 CounterLive 模組
    live("/counter", CounterLive)

    get("/", PageController, :index)
  end

LiveView Module

既然都指了,就要把他補上
通常 LiveView 都會放在跟 controllers 資料夾同級的 live 資料夾裡
以我們的專案來看是 lib/blog_web/live

lib/blog_web/live 資料夾裡面建立 counter_live.ex 來裝我們這次要使用的 CounterLive 模組

lib/blog_web/live/counter_live.ex

defmodule BlogWeb.CounterLive do
  # 使用 BlogWeb 裡面的 live_view 模組們
  use BlogWeb, :live_view

  # mount 是每次 LiveView 頁面一連線會執行的地方,我們待會會在這邊初始 LiveView 的狀態
  def mount(_params, _session, socket) do
    {:ok, socket}
  end

  # 準備顯示在頁面上的內容
  def render(assigns) do
    ~H"""
    <h1>簡陋計數器</h1>
    """
  end
end

https://ithelp.ithome.com.tw/upload/images/20220925/20141054NFAYwly5TI.png

這樣其實就只是一個不會動的普通頁面,不過我們先把需要的零件加進去 render 方法裡面

  def render(assigns) do
    ~H"""
    <h1>簡單計數器</h1>

    <section>
      <h1>0</h1>
      <button>+</button>
      <button>-</button>
    </section>
    """
  end

https://ithelp.ithome.com.tw/upload/images/20220925/20141054o9PtClF0d6.png

assigns

接著我們要把畫面上寫死的 0 改由狀態管理,
LiveView 的頁面狀態都放在 socket 裡面的 assigns
我們可以用 assign 方法把 我們要放的 key value 值放進去

  def mount(_params, _session, socket) do
    socket = assign(socket, :number, 0)
    {:ok, socket}
  end

一但有值在 assigns 裡面,他就可以在 render 裡用取用
這次來說我們在加了 :number
所以在 render 的 ~H sigil 裡面可以使用 @number 來取他的值

  def render(assigns) do
    ~H"""
    <h1>簡單計數器</h1>

    <section>
      <h1><%= @number %></h1>
      <button>+</button>
      <button>-</button>
    </section>
    """
  end

動起來

有寫過前端框架的朋友可能會開始覺得這個套路有點熟悉,
沒錯,接下來我們要在 上面綁上動作來操作狀態

  def render(assigns) do
    ~H"""
    <h1>簡單計數器</h1>

    <section>
      <h1><%= @number %></h1>
      <button phx-click="plus">+</button>
      <button phx-click="minus">-</button>
    </section>
    """
  end

好了之後,我們要用 handle_event 這個 callback 方法來接這兩個事件

  def handle_event("plus", _params, socket) do
    # 從 socket 的 assigns 的 number 拿到加之前的數字 然後加一
    new_number = socket.assigns.number + 1
    # 在這邊用 assign 再幫 :number 上新的值
    socket = assign(socket, :number, new_number)
    # handle_event 用的是 :noreply,代表他只有單純更新 socket,畫面則是統一由 LiveView 依照狀態來與瀏覽器溝通更新
    {:noreply, socket}
  end

  # 跟上面一樣只是換成 -
  def handle_event("minus", _params, socket) do
    socket = assign(socket, :number, socket.assigns.number - 1)
    {:noreply, socket}
  end

這樣就完成啦!
按下按鈕改變 number 的狀態,畫面上就會自動更新,不需要自己去改變 DOM


上一篇
{20, LiveView, "LiveView構造"}
下一篇
{22, LiveView, "列表與Component"}
系列文
速成 Phoenix, 2022年最受喜愛框架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言