Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updating child components via a parent method #666

Open
jacksund opened this issue Feb 26, 2024 · 4 comments
Open

updating child components via a parent method #666

jacksund opened this issue Feb 26, 2024 · 4 comments

Comments

@jacksund
Copy link
Contributor

jacksund commented Feb 26, 2024

Branching from #662

I have a question about going one step beyond your example in the docs -- Can force_render be applied to a list of children components? I'm struggling to get this to work as expected. For example say I add the following method & html to the table component:

# method added to TableView

def begin_edit_all(self):
    for child in self.children:
        if hasattr(child, "is_editing"):
            print("child set to editting")
            child.is_editing = True
            # child.force_render = True  # doesn't trigger refresh
    # self.force_render = True # doesn't trigger refresh
<button unicorn:click="begin_edit_all"
        type="button">
    Edit All
</button>

My attempts to force_render child components fail. And as a more complex example, using filter + begin_edit_all applies to all books rather than those that have been filtered:

image

Here are the files for this example:
mysite_example3.zip

A more realistic example of this would involve a table where you want to apply a status to all child components. For example, we could have a list of tasks that are filtered down and then you apply a set_status_complete to these filters items - that updates the table + status column.

@alexandry-augustin
Copy link

Hi,

I can confirm that I am also witnessing the behaviour you've described.

I would also highlight an even simpler case taken from the example in the documentation. It seems that setting the value of children from the parent doesn't produce the desired effect:

    def load_table(self):
        self.books = Book.objects.all()

        for child in self.children:
            if hasattr(child, "is_editing"):
                child.is_editing = True # This is not having any effect whatsoever

@jacksund
Copy link
Contributor Author

@adamghill this issue was raised in priority for me so I started to revisit it last week, and I believe I found the issue.

The bug looks to be coming from the caching process. Using my begin_edit_all function above as an example, here's what happens:

  1. initial page load happens where parent+child components are created & added to the cache
  2. user clicks button that calls begin_edit_all in order to modify all children
  3. parent + child components loaded from the cache
  4. parent method begin_edit_all is called that modifies children
  5. BUG: only the parent is saved back to the cache, and the children are not!
  6. the component is re-rendered, including the child components that use the {% unicorn ... key=... %} tag. However, the tag pulls the cached version of the child, which has not been updated. Therefore, methods like begin_edit_all will give back a "not modified" response

@jacksund
Copy link
Contributor Author

jacksund commented Nov 11, 2024

EDIT: this unfortunately isn't the solution. see comments below

Here's my guess at a quick fix. You can add the line self._cache_component() to bottom of your method to ensure all the updated child components are re-cached. For example:

# method added to TableView

def begin_edit_all(self):
    for child in self.children:
        if hasattr(child, "is_editing"):
            print("child set to editting")
            child.is_editing = True
    self._cache_component()  # BUG-FIX

@jacksund
Copy link
Contributor Author

another update -- the fix looks to be more involved because children data isn't updated in the frontend js (even even if it shows correct data in the html). So when the next message is sent to the backend, old component.data bubbles back up and undoes anything done with begin_edit_all

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants