关于phoenix:使用-Phoenix-LiveView-构建-Instagram-8

应用PETAL(Phoenix、Elixir、TailwindCSS、AlpineJS、LiveView)技术栈构建一个简化版的Instagram Web应用程序<!--more--> 在第 7 局部中,咱们在顶部题目导航菜单中增加了搜寻性能,在这部分中,咱们将钻研书签性能,并在以下内容向咱们的主页增加新帖子时告诉用户。您能够赶上Instagram 克隆 GitHub Repo。 当咱们尝试创立未抉择图像的新帖子时,让咱们处理错误,为此,咱们须要在外部的保留句柄函数中正确进行模式匹配lib/instagram_clone_web/live/post_live/new.ex: def handle_event("save", %{"post" => post_params}, socket) do post = PostUploader.put_image_url(socket, %Post{}) case Posts.create_post(post, post_params, socket.assigns.current_user) do {:ok, %{post: post}} -> # <- THIS LINE WAS UPDATED PostUploader.save(socket) {:noreply, socket |> put_flash(:info, "Post created successfully") |> push_redirect(to: Routes.user_profile_path(socket, :index, socket.assigns.current_user.username))} |> push_redirect(to: Routes.live_path(socket, InstagramCloneWeb.PostLive.Show, post.url_id))} {:error, :post, %Ecto.Changeset{} = changeset, %{}} -> # <- THIS LINE WAS UPDATED {:noreply, assign(socket, changeset: changeset)} end end因为咱们用来Ecto.Multi更新用户的帖子计数并创立帖子,所以在后果中咱们必须进行相应的模式匹配。 ...

September 1, 2023 · 10 min · jiezi

关于phoenix:使用-Phoenix-LiveView-构建-Instagram-7

应用PETAL(Phoenix、Elixir、TailwindCSS、AlpineJS、LiveView)技术栈构建一个简化版的Instagram Web应用程序<!--more--> 在第 6 局部中,咱们增加了主页,在这部分中,咱们将钻研顶部题目导航菜单中的搜寻性能。您能够赶上Instagram 克隆 GitHub Repo。 搜寻性能将提供按用户名或全名搜寻用户的能力,咱们只须要一个蕴含头像 URL、用户名和全名的地图,让咱们增加一个函数来在咱们的帐户上下文中获取它。外面lib/instagram_clone/accounts.ex: ... def search_users(q) do User |> where([u], ilike(u.username, ^"%#{q}%")) |> or_where([u], ilike(u.full_name, ^"%#{q}%")) |> select([u], map(u, [:avatar_url, :username, :full_name])) |> Repo.all() end...咱们将解决该事件以在标头导航组件 open 中进行搜寻lib/instagram_clone_web/templates/layout/live.html.leex,而后将 ID 发送到咱们的组件以便可能解决该事件: <%= if @current_user do %> <%= live_component @socket, InstagramCloneWeb.HeaderNavComponent, id: 1, current_user: @current_user %><% else %> <%= if @live_action !== :root_path do %> <%= live_component @socket, InstagramCloneWeb.HeaderNavComponent, id: 1, current_user: @current_user %> <% end %><% end %><main role="main" class="container mx-auto max-w-full md:w-11/12 2xl:w-6/12 pt-24"> <p class="alert alert-info" role="alert" phx-click="lv:clear-flash" phx-value-key="info"><%= live_flash(@flash, :info) %></p> <p class="alert alert-danger" role="alert" phx-click="lv:clear-flash" phx-value-key="error"><%= live_flash(@flash, :error) %></p> <%= @inner_content %></main>在外面lib/instagram_clone_web/live/header_nav_component.html.leex让咱们应用 AlpineJs 关上 UL,当输出至多有一个字母时,咱们将在其中显示后果,如果外面没有任何内容或单击输出,则不会显示任何内容。让咱们应用phx-change表单事件来运行咱们的搜寻,咱们还将调配给咱们的套接字 a@overflow_y_scroll_ul以在后果大于 6 时显示滚动条。 ...

September 1, 2023 · 6 min · jiezi

关于phoenix:使用-Phoenix-LiveView-构建-Instagram-6

应用PETAL(Phoenix、Elixir、TailwindCSS、AlpineJS、LiveView)技术栈构建一个简化版的Instagram Web应用程序<!--more--> 在第 5 局部中,咱们增加了 show-post 页面,在这部分中,咱们将在主页上进行工作。您能够赶上Instagram 克隆 GitHub Repo。 首先,咱们在 posts 上下文中增加一个函数来获取 feed,而后增加另一个函数来获取 feed 的总数 open lib/instagram_clone/posts.ex: @doc """ Returns the list of paginated posts of a given user id And posts of following list of given user id With user and likes preloaded With 2 most recent comments preloaded with user and likes User, page, and per_page are given with the socket assigns ## Examples iex> get_accounts_feed(following_list, assigns) [%{photo_url: "", url_id: ""}, ...] """ def get_accounts_feed(following_list, assigns) do user = assigns.current_user page = assigns.page per_page = assigns.per_page query = from c in Comment, select: %{id: c.id, row_number: over(row_number(), :posts_partition)}, windows: [posts_partition: [partition_by: :post_id, order_by: [desc: :id]]] comments_query = from c in Comment, join: r in subquery(query), on: c.id == r.id and r.row_number <= 2 Post |> where([p], p.user_id in ^following_list) |> or_where([p], p.user_id == ^user.id) |> limit(^per_page) |> offset(^((page - 1) * per_page)) |> order_by(desc: :id) |> preload([:user, :likes, comments: ^{comments_query, [:user, :likes]}]) |> Repo.all() end def get_accounts_feed_total(following_list, assigns) do user = assigns.current_user Post |> where([p], p.user_id in ^following_list) |> or_where([p], p.user_id == ^user.id) |> select([p], count(p.id)) |> Repo.one() end咱们须要以下列表,在外面lib/instagram_clone/accounts.ex增加以下函数: ...

September 1, 2023 · 13 min · jiezi

关于phoenix:使用-Phoenix-LiveView-构建-Instagram-5

应用PETAL(Phoenix、Elixir、TailwindCSS、AlpineJS、LiveView)技术栈构建一个简化版的Instagram Web应用程序<!--more--> 在第 4 局部中,咱们增加了个人资料帖子局部和帖子页面,在这部分中,咱们将解决显示帖子页面。您能够赶上Instagram 克隆 GitHub Repo。 让咱们首先为显示页面增加根本模板,关上lib/instagram_clone_web/live/post_live/show.html.leex并增加以下内容: <section class="flex"> <!-- Post Image section --> <%= img_tag @post.photo_url, class: "w-3/5 object-contain h-full" %> <!-- End Post Image section --> <div class="w-2/5 border-2 h-full"> <div class="flex p-4 items-center border-b-2"> <!-- Post header section --> <%= live_redirect to: Routes.user_profile_path(@socket, :index, @post.user.username) do %> <%= img_tag @post.user.avatar_url, class: "w-8 h-8 rounded-full object-cover object-center" %> <% end %> <div class="ml-3"> <%= live_redirect @post.user.username, to: Routes.user_profile_path(@socket, :index, @post.user.username), class: "truncate font-bold text-sm text-gray-500 hover:underline" %> </div> <!-- End post header section --> </div> <div class="no-scrollbar h-96 overflow-y-scroll p-4 flex flex-col"> <%= if @post.description do %> <!-- Description section --> <div class="flex mt-2"> <%= live_redirect to: Routes.user_profile_path(@socket, :index, @post.user.username) do %> <%= img_tag Avatar.get_thumb(@post.user.avatar_url), class: "w-8 h-8 rounded-full object-cover object-center" %> <% end %> <div class="px-4 w-11/12"> <%= live_redirect @post.user.username, to: Routes.user_profile_path(@socket, :index, @post.user.username), class: "font-bold text-sm text-gray-500 hover:underline" %> <span class="text-sm text-gray-700"> <p class="inline"><%= @post.description %></p></span> </span> <div class="flex mt-3"> <div class="text-gray-400 text-xs"><%= Timex.from_now @post.inserted_at %></div> </div> </div> </div> <!-- End Description Section --> <% end %> </div> <div class="w-full border-t-2"> <!-- Action icons section --> <div class="flex pl-4 pr-2 pt-2"> <div class="w-8 h-8 cursor-pointer"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" /> </svg> <svg class="hidden text-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> <path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd" /> </svg> </div> <div class="ml-4 w-8 h-8 cursor-pointer"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /> </svg> </div> <div class="ml-4 w-8 h-8 cursor-pointer"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" /> </svg> </div> <div class="w-8 h-8 ml-auto cursor-pointer"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" /> </svg> </div> </div> <!-- End Action icons section --> <!-- Description section --> <button class="px-5 text-xs text-gray-500 font-bold focus:outline-none"><%= @post.total_likes %> likes</button> <h6 class="px-5 text-xs text-gray-400"><%= Timex.format!(@post.inserted_at, "{Mfull} {D}, {YYYY}") %></h6> <!-- End Description Section --> <!-- Comment input section --> <div class="p-2 flex items-center mt-3 border-t-2 border-gray-100"> <div class="w-full"> <textarea aria-label="Add a comment..." placeholder="Add a comment..." class="w-full border-0 focus:ring-transparent resize-none" autocomplete="off" autocorrect="off" rows="1"></textarea> </div> <div><button class="text-light-blue-500 font-bold pb-2 text-sm">Post</button></div> </div> <!-- End Comment input section --> </div> </div></section>关上assets/css/app.scss并将以下款式增加到文件底部,以使页面评论局部不显示滚动条: ...

September 1, 2023 · 11 min · jiezi

关于phoenix:Phoenix单机版安装遇到的启动问题

1.sqlline.py 启动报错。起因是Phoenix不反对python3,应用python2执行 Traceback (most recent call last): File "./bin/sqlline.py", line 25, in <module> import phoenix_utils File "/Users/bigdata/phoenix/phoenix_5_0/bin/phoenix_utils.py", line 208 print "phoenix_class_path:", phoenix_class_path ^SyntaxError: Missing parentheses in call to 'print'. Did you mean print("phoenix_class_path:", phoenix_class_path)?具体操作: /usr/bin/python2 /Users/bigdata/phoenix/phoenix_5_0/bin/sqlline.py localhost:2181/hbase再次启动,遇到以下问题: phoenix RpcRetryingCaller{globalStartTime=1661941384669, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.PleaseHoldException: org.apache.hadoop.hbase.PleaseHoldException: Master is initializing解决办法:1.停掉hbase,stop-hbase.sh2.停掉zookeeper,zkServer.sh stop3.删除hdfs中的/hbase目录,删除zookeeper中/hbase目录hdfs: hdfs dfs -rm -r /hbasezookeeper: deleteall /hbase4.启动zookeeper5.启动hbase 再次启动:

August 31, 2022 · 1 min · jiezi