Browse Source

avoid hiding BindableProperty by property decorator, use new value-change handler instead

Falko Schindler 3 years ago
parent
commit
ef30b4e71a
3 changed files with 13 additions and 14 deletions
  1. 7 1
      nicegui/binding.py
  2. 2 10
      nicegui/elements/element.py
  3. 4 3
      nicegui/elements/value_element.py

+ 7 - 1
nicegui/binding.py

@@ -2,7 +2,7 @@
 import asyncio
 from collections import defaultdict
 from justpy.htmlcomponents import HTMLBaseComponent
-from typing import Any, Callable, Set, Tuple
+from typing import Any, Callable, Optional, Set, Tuple
 from .task_logger import create_task
 
 bindings = defaultdict(list)
@@ -65,6 +65,9 @@ def bind_from(self_obj: Any, self_name: str, other_obj: Any, other_name: str, ba
 
 class BindableProperty:
 
+    def __init__(self, on_change: Optional[Callable] = None):
+        self.on_change = on_change
+
     def __set_name__(self, _, name: str):
         self.name = name
 
@@ -72,6 +75,9 @@ class BindableProperty:
         return getattr(owner, '_' + self.name)
 
     def __set__(self, owner: Any, value: Any):
+        value_changed = getattr(owner, '_' + self.name, value) != value
         setattr(owner, '_' + self.name, value)
         bindable_properties[(id(owner), self.name)] = owner
         update_views(propagate(owner, self.name))
+        if value_changed and self.on_change is not None:
+            self.on_change(owner, value)

+ 2 - 10
nicegui/elements/element.py

@@ -3,7 +3,8 @@ from ..binding import bind_from, bind_to, BindableProperty
 from ..globals import view_stack, page_stack
 
 class Element:
-    visible = BindableProperty()
+    visible = BindableProperty(
+        on_change=lambda sender, visible: (sender.view.remove_class if visible else sender.view.set_class)('hidden'))
 
     def __init__(self,
                  view: jp.HTMLBaseComponent,
@@ -16,15 +17,6 @@ class Element:
 
         self.visible = True
 
-    @property
-    def visible(self):
-        return self.visible_
-
-    @visible.setter
-    def visible(self, visible: bool):
-        self.visible_ = visible
-        (self.view.remove_class if self.visible_ else self.view.set_class)('hidden')
-
     def bind_visibility_to(self, target_object, target_name, forward=lambda x: x):
         bind_to(self, 'visible', target_object, target_name, forward=forward)
         return self

+ 4 - 3
nicegui/elements/value_element.py

@@ -6,7 +6,10 @@ from ..binding import bind_from, bind_to, BindableProperty
 from .element import Element
 
 class ValueElement(Element):
-    value = BindableProperty()
+    value = BindableProperty(
+        on_change=lambda sender, value: handle_event(sender.change_handler,
+                                                     ValueChangeEventArguments(sender=sender, value=value),
+                                                     update=sender.parent_view))
 
     def __init__(self,
                  view: jp.HTMLBaseComponent,
@@ -25,8 +28,6 @@ class ValueElement(Element):
 
     def handle_change(self, msg):
         self.value = msg['value']
-        arguments = ValueChangeEventArguments(sender=self, value=self.value)
-        handle_event(self.change_handler, arguments, update=self.parent_view)
 
     def bind_value_to(self, target_object, target_name, *, forward=lambda x: x):
         bind_to(self, 'value', target_object, target_name, forward=forward)