-
-
Notifications
You must be signed in to change notification settings - Fork 627
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
ui.refreshable
with ui.state
in an instance method
#3392
Comments
It works well after modify. from nicegui import ui
class Counter:
def __init__(self, name: str):
self.name = name
def counter(self):
@ui.refreshable_method # or @ui.refreshable, same result
def counter():
with ui.card():
count, set_count = ui.state(0)
color, set_color = ui.state("black")
ui.label(f"{self.name} = {count}").classes(f"text-{color}")
ui.button(f"{self.name} += 1", on_click=lambda: set_count(count + 1))
ui.select(["black", "red", "green", "blue"], value=color, on_change=lambda e: set_color(e.value))
return counter()
with ui.row():
Counter("A").counter()
Counter("B").counter()
ui.run() |
Thanks! I understand we can make it work with a closure like this, but it feels like a kludge. The lifecycle for "refreshables" is mysterious enough as it is. 🙂 |
Another example,maybe you needn't create a new instance but call it twice. from nicegui import ui
class Counter:
def __init__(self, name: str):
self.name = name
@ui.refreshable # or @ui.refreshable, same result
def counter(self,name=None):
with ui.card():
count, set_count = ui.state(0)
color, set_color = ui.state("black")
ui.label(f"{self.name if name is None else name} = {count}").classes(f"text-{color}")
ui.button(f"{self.name if name is None else name} += 1", on_click=lambda: set_count(count + 1))
ui.select(["black", "red", "green", "blue"], value=color, on_change=lambda e: set_color(e.value))
with ui.row():
a = Counter("A")
a.counter()
a.counter('B')
ui.run() |
@python-and-fiction thanks for the workarounds. For now I've concluded that ui.state doesn't fit my use case. I'll come back to that later, in discussions. @falkoschindler , @rodja et al, I flagged the issue because I think it's a bug or an anomaly. If it's an edge case that can be ignored, please close the issue. |
That's an interesting problem, @kleynjan! I think we should leave it open as a bug. I just experimented with your code class Counter:
def __init__(self, name: str) -> None:
self.name = name
@ui.refreshable_method
def counter(self) -> None:
with ui.card():
count, set_count = ui.state(0)
ui.label(f'{self.name} = {count}')
ui.button(f'{self.name} += 1', on_click=lambda: set_count(count + 1))
Counter('A').counter()
Counter('B').counter() and it looks like some I also compared it to the non-OOP variant @ui.refreshable
def counter(name: str) -> None:
with ui.card():
count, set_count = ui.state(0)
ui.label(f'{name} = {count}')
ui.button(f'{name} += 1', on_click=lambda: set_count(count + 1))
with ui.row():
counter('C')
counter('D') which works in principal, but seems to update both cards C and D when incrementing the counter. In case you have many counters on a page, this causes quite some overhead. Maybe that's related to the OOP problem. |
ui.refreshable
with ui.state
in an instance method
Description
Below is an OO variant of the "counter" example given in the docs for ui.state. Only counter B gets working
set_count
andset_color
functions. I've tried to move variables and setters to__init__
asself.counter
,self.set_counter
etc but that doesn't help.Looking at ui.state source in refreshable.py, the state variables and setters functions are added to the local scope of the current target, but that mechanism seems to be broken when the
@refreshable
is a method?This is on 1.4.29.
The text was updated successfully, but these errors were encountered: