adamghill / django-unicorn

The magical reactive component framework for Django ✨
https://www.django-unicorn.com
MIT License
2.38k stars 119 forks source link

[Bug] Child component is not reactive #738

Open sergiopmdeveloper opened 6 days ago

sergiopmdeveloper commented 6 days ago

Bug Description

I have a for loop inside a component that renders multiple times a child component (a table with rows). These rows contain a button that updates the state of the component to show a modal in a reactive way. This interaction works, what is not displayed reactively is the modal when the state has changed. I have tried everything but nothing works.

The property that does not work in a reactive way is displayed_modal, and I can assure you that the change from False to True does occur because I have debugged it. It is not a problem with the interface either, because when you load the page with this status set to True for testing purposes, the modals are displayed. What doesn't work is the reactivity.

Expected behaviour

The modal is displayed in a reactive manner based on the change of state.

Screenshots / Screenrecords

Parent component:

from django.db.models.query import QuerySet from django_unicorn.components import UnicornView

from apps.passwords.models import Password from authentication.models import AppUser

class PasswordTableView(UnicornView): """ Password table component """

user_passwords: QuerySet[Password]

def mount(self) -> None:
    """
    Mounts the component
    """

    self.load_passwords()

def load_passwords(self) -> None:
    """
    Loads passwords
    """

    user: AppUser = self.request.user

    self.user_passwords = user.passwords.all()

Parent template:

{# Password table component #}

{% load unicorn %}

Passwords

{% if not user_passwords %} {% endif %} {% for password in user_passwords %} {% unicorn 'password-row' password=password key=password.id %} {% endfor %}
Name Password Username Email Site Actions
No passwords found

Child component:

from django_unicorn.components import UnicornView

from apps.passwords.components.password_table import PasswordTableView from apps.passwords.models import Password

class PasswordRowView(UnicornView): """ Password table component """

password: Password
displayed_modal = False

def display_modal(self) -> None:
    """
    Displays a modal

    Parameters
    ----------
    modal_id : str
        The id of the modal to display
    """

    self.displayed_modal = True

def hide_modal(self) -> None:
    """
    Hides the modal
    """

    self.displayed_modal = False

def delete_password(self, password_id: int) -> None:
    """
    Deletes a password
    """

    password = Password.objects.get(id=password_id)
    password.delete()

    parent: PasswordTableView = self.parent
    parent.load_passwords()

Child template:

{{ password.name }}

**********

{{ password.username|default:"..." }} {{ password.email|default:"..." }} {% if password.site %} {{ password.site }} {% else %} ... {% endif %}
{% if displayed_modal %}

Warning

You are about to delete the password {{ password.name }}. Are you sure you want to proceed?

{% endif %}

Steps to reproduce

No response

What browsers are you seeing the problem on?

No response

👀 Have you checked for similar open issues?

Code of Conduct

Are you willing to work on this issue ?

None

sergiopmdeveloper commented 5 days ago

IMPORTANT

Is related to the use of table tags (th, td and tr) in a child component. When I replace them with normal tags like div, h1, p or span it works perfectly. So this is a bug related to the table tags!!!!