- 
      
 - 
        
Save aerosol/57bb9ebf39c64ff91a15ed09d7ba9909 to your computer and use it in GitHub Desktop.  
    Liveview dynamic rendering issue
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | #!/usr/bin/env elixir | |
| # Minimal Phoenix LiveView single file example | |
| # Run with: elixir minimal_liveview.exs | |
| # Access at: http://localhost:4001 | |
| Application.put_env(:minimal_app, MinimalApp.Endpoint, | |
| http: [ip: {127, 0, 0, 1}, port: 4001], | |
| server: true, | |
| live_view: [signing_salt: "aaaaaaaa"], | |
| secret_key_base: String.duplicate("a", 64), | |
| debug_errors: true | |
| ) | |
| Mix.install([ | |
| {:plug_cowboy, "~> 2.5"}, | |
| {:jason, "~> 1.0"}, | |
| {:phoenix, "~> 1.7"}, | |
| {:phoenix_live_view, "~> 1.0"} | |
| ]) | |
| defmodule MinimalApp.ErrorHTML do | |
| def render(template, _assigns) do | |
| Phoenix.Controller.status_message_from_template(template) | |
| end | |
| end | |
| defmodule MinimalApp.Layouts do | |
| use Phoenix.Component | |
| def app(assigns) do | |
| ~H""" | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <meta name="csrf-token" content={Plug.CSRFProtection.get_csrf_token()} /> | |
| <title>Minimal LiveView</title> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/priv/static/phoenix.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/priv/static/phoenix_live_view.min.js"></script> | |
| <style> | |
| body { font-family: system-ui, sans-serif; margin: 40px; } | |
| .container { max-width: 800px; } | |
| button { padding: 8px 16px; margin: 4px; background: #3b82f6; color: white; border: none; border-radius: 4px; cursor: pointer; } | |
| button:hover { background: #2563eb; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <%= @inner_content %> | |
| </div> | |
| <script> | |
| let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") | |
| let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket, {params: {_csrf_token: csrfToken}}) | |
| liveSocket.connect() | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| end | |
| end | |
| defmodule MinimalApp.Components do | |
| use Phoenix.Component | |
| attr(:type, :string, default: nil) | |
| attr(:class, :string, default: nil) | |
| attr(:rest, :global, include: ~w(disabled form name value)) | |
| slot(:inner_block, required: true) | |
| def button(assigns) do | |
| ~H""" | |
| <button | |
| type={@type} | |
| class={@class} | |
| {@rest} | |
| > | |
| {render_slot(@inner_block)} | |
| </button> | |
| """ | |
| end | |
| attr(:class, :string, default: "") | |
| attr(:as, :any, default: nil) | |
| slot(:inner_block, required: true) | |
| def dropdown_trigger(assigns) do | |
| {fun, assigns} = Map.pop(assigns, :as) | |
| fun.(assigns) | |
| end | |
| end | |
| defmodule MinimalApp.HomeLive do | |
| use Phoenix.LiveView | |
| import MinimalApp.Components | |
| def mount(_params, _session, socket) do | |
| {:ok, socket} | |
| end | |
| def render(assigns) do | |
| ~H""" | |
| <.dropdown_trigger as={&MinimalApp.Components.button/1}> | |
| inner block is required | |
| </.dropdown_trigger> | |
| """ | |
| end | |
| end | |
| defmodule MinimalApp.Router do | |
| use Phoenix.Router | |
| import Phoenix.Controller | |
| import Phoenix.LiveView.Router | |
| pipeline :browser do | |
| plug(:accepts, ["html"]) | |
| plug(:fetch_session) | |
| plug(:fetch_live_flash) | |
| plug(:put_root_layout, html: {MinimalApp.Layouts, :app}) | |
| plug(:protect_from_forgery) | |
| end | |
| scope "/", MinimalApp do | |
| pipe_through(:browser) | |
| live("/", HomeLive) | |
| end | |
| end | |
| defmodule MinimalApp.Endpoint do | |
| use Phoenix.Endpoint, otp_app: :minimal_app | |
| @session_options [ | |
| store: :cookie, | |
| key: "_minimal_app_key", | |
| signing_salt: "aaaaaaaa" | |
| ] | |
| socket("/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]) | |
| plug(Plug.RequestId) | |
| plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint]) | |
| plug(Plug.Parsers, | |
| parsers: [:urlencoded, :multipart, :json], | |
| pass: ["*/*"], | |
| json_decoder: Phoenix.json_library() | |
| ) | |
| plug(Plug.MethodOverride) | |
| plug(Plug.Head) | |
| plug(Plug.Session, @session_options) | |
| plug(MinimalApp.Router) | |
| end | |
| # Start the application | |
| {:ok, _} = Supervisor.start_link([MinimalApp.Endpoint], strategy: :one_for_one) | |
| IO.puts("\n๐ Minimal Phoenix LiveView started!") | |
| IO.puts("๐ฑ Open http://localhost:4001 in your browser") | |
| IO.puts("๐ Press Ctrl+C to stop\n") | |
| Process.sleep(:infinity) | |
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment