LiveView不会在控制台中抛出CID错误的组件

问题描述 投票:0回答:1

我有一个名为Menu的实时取景,其中包含3个实时组件CategoriesProductsVariants

phx-click设置了每个类别,产品,因此,当单击类别时,handle_event将返回assign(socket,:products,products)ProductsComponent将为单击类别的产品,然后单击product,将显示变体。

并且handle_events在菜单视图中

defmodule MyAppWeb.Admin.LocationLive.Menu do
  use MyAppWeb, :live_view

  import MyAppWeb.Admin.LocationLive.Helpers,
    only: [
      get_categories: 1,
      get_products: 2,
      get_variants: 2
    ]

  alias MyApp.Manager.Base

  @impl true
  def mount(%{"id" => location_id}, _session, socket) do
    case Base.get_location(location_id) do
      nil ->
        {:noreply, redirect(socket, Routes.admin_business_path(MyAppWeb.Endpoint, :index))}

      location ->
        {:ok,
         socket
         |> assign(:page_title, "Menu")
         |> assign(:location, location)
         |> assign(:products, [])
         |> assign(:variants, [])
         |> assign(:selected_category_id, nil)
         |> assign(:selected_product_id, nil)
         |> assign(:categories, get_categories(location)), temporary_assigns: [categories: []]}
    end
  end

  @impl true
  def handle_event(
        "show-products",
        %{"category" => category_id},
        socket
      ) do
    location = get_location(socket)

    {:noreply,
     socket
     |> assign(:products, get_products(location, category_id))
     |> assign(:variants, [])
     |> assign(:selected_category_id, category_id)}
  end

  @impl true
  def handle_event(
        "show-variants",
        %{"product" => product_id},
        socket
      ) do
    location = get_location(socket)

    {:noreply,
     socket
     |> assign(:variants, get_variants(location, product_id))
     |> assign(:selected_product_id, product_id)}
  end

  defp get_location(socket) do
    socket.assigns.location
  end
end

menu.html.leex

<div class="row">
  <div class="<%= row_parts_class(4) %>">
    <div class="align-items-center <%= row_parts_class(12) %>">
      <h5 class="h5 font-weight-bold text-default">Categories</h5>
    </div>
    <%= live_component @socket, MyAppWeb.Admin.LocationLive.CategoriesComponent,
      categories: @categories,
      location: @location,
      id: "categories-component"
    %>
  </div>
  <div class="<%= row_parts_class(4) %>">
    <div class="align-items-center <%= row_parts_class(12) %>">
      <h5 class="h5 font-weight-bold text-default">Products</h5>
    </div>
    <%= live_component @socket, MyAppWeb.Admin.LocationLive.ProductsComponent,
      products: @products,
      location: @location,
      category_id: @selected_category_id,
      id: "products-component"
    %>
  </div>
  <div class="<%= row_parts_class(4) %>">
    <div class="align-items-center <%= row_parts_class(12) %>">
      <h5 class="h5 font-weight-bold text-default">Variants</h5>
    </div>
    <%= live_component @socket, MyAppWeb.Admin.LocationLive.VariantsComponent,
      variants: @variants,
      location: @location,
      product_id: @selected_product_id,
      id: "variants-component"
    %>
  </div>
</div>

我的问题是,点击产品后,会显示变体,然后我再单击一次类别,它将显示新产品,但是旧的变体仍然存在。因此,我尝试在类别handle_event中使用assign(socket, :variants, []),但是它在控制台no component for CID 2中引发了错误,并且旧的Products和Variants组件保持不变。

enter image description here

任何人都不知道如何解决此问题,或者有解决方法,每次单击类别时都会清除VariantsComponent?

谢谢!

phoenix-framework phoenix-live-view
1个回答
0
投票

[玩完之后,通过将selected_product_id设置为nil,并在Variants实时组件周围放置了if语句,我可以隐藏这些变体

<%= if @selected_product_id do %>
  <%= live_component @socket, MyAppWeb.Admin.LocationLive.VariantsComponent,
    variants: @variants,
    location: @location,
    product_id: @selected_product_id,
    id: "variants-component"
  %>
<% end %>

和菜单内部

{:noreply,
 socket
 |> assign(:products, get_products(location, category_id))
 |> assign(:selected_product_id, nil)
 |> assign(:selected_category_id, category_id)}

我想这样,当实时视图将更改推送到视图时,它将检查是否应渲染实时组件,当selected_product_id为零时,最终将隐藏变体组件

© www.soinside.com 2019 - 2024. All rights reserved.