Call event handlers from other event handlers (#691)
This commit is contained in:
parent
7067baf176
commit
592be487c9
@ -394,6 +394,8 @@ class App(Base):
|
|||||||
# Compile the custom components.
|
# Compile the custom components.
|
||||||
compiler.compile_components(custom_components)
|
compiler.compile_components(custom_components)
|
||||||
|
|
||||||
|
self.state.convert_handlers_to_fns()
|
||||||
|
|
||||||
|
|
||||||
async def process(
|
async def process(
|
||||||
app: App, event: Event, sid: str, headers: Dict, client_ip: str
|
app: App, event: Event, sid: str, headers: Dict, client_ip: str
|
||||||
|
@ -51,6 +51,9 @@ class State(Base, ABC):
|
|||||||
# Backend vars inherited
|
# Backend vars inherited
|
||||||
inherited_backend_vars: ClassVar[Dict[str, Any]] = {}
|
inherited_backend_vars: ClassVar[Dict[str, Any]] = {}
|
||||||
|
|
||||||
|
# The event handlers.
|
||||||
|
event_handlers: ClassVar[Dict[str, EventHandler]] = {}
|
||||||
|
|
||||||
# The parent state.
|
# The parent state.
|
||||||
parent_state: Optional[State] = None
|
parent_state: Optional[State] = None
|
||||||
|
|
||||||
@ -181,8 +184,18 @@ class State(Base, ABC):
|
|||||||
}
|
}
|
||||||
for name, fn in events.items():
|
for name, fn in events.items():
|
||||||
event_handler = EventHandler(fn=fn)
|
event_handler = EventHandler(fn=fn)
|
||||||
|
cls.event_handlers[name] = event_handler
|
||||||
setattr(cls, name, event_handler)
|
setattr(cls, name, event_handler)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def convert_handlers_to_fns(cls):
|
||||||
|
"""Convert the event handlers to functions.
|
||||||
|
|
||||||
|
This is done so the state functions can be called as normal functions during runtime.
|
||||||
|
"""
|
||||||
|
for name, event_handler in cls.event_handlers.items():
|
||||||
|
setattr(cls, name, event_handler.fn)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
def get_parent_state(cls) -> Optional[Type[State]]:
|
def get_parent_state(cls) -> Optional[Type[State]]:
|
||||||
@ -545,7 +558,7 @@ class State(Base, ABC):
|
|||||||
path = event.name.split(".")
|
path = event.name.split(".")
|
||||||
path, name = path[:-1], path[-1]
|
path, name = path[:-1], path[-1]
|
||||||
substate = self.get_substate(path)
|
substate = self.get_substate(path)
|
||||||
handler = getattr(substate, name)
|
handler = substate.event_handlers[name] # type: ignore
|
||||||
|
|
||||||
# Process the event.
|
# Process the event.
|
||||||
fn = functools.partial(handler.fn, substate)
|
fn = functools.partial(handler.fn, substate)
|
||||||
|
@ -204,6 +204,33 @@ def test_class_vars(test_state):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_event_handlers(test_state):
|
||||||
|
"""Test that event handler is set correctly.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
test_state: A state.
|
||||||
|
"""
|
||||||
|
expected = {
|
||||||
|
"change_both",
|
||||||
|
"do_nothing",
|
||||||
|
"do_something",
|
||||||
|
"set_array",
|
||||||
|
"set_complex",
|
||||||
|
"set_count",
|
||||||
|
"set_fig",
|
||||||
|
"set_key",
|
||||||
|
"set_mapping",
|
||||||
|
"set_num1",
|
||||||
|
"set_num2",
|
||||||
|
"set_obj",
|
||||||
|
"set_value",
|
||||||
|
"set_value2",
|
||||||
|
}
|
||||||
|
|
||||||
|
cls = type(test_state)
|
||||||
|
assert set(cls.event_handlers.keys()).intersection(expected) == expected
|
||||||
|
|
||||||
|
|
||||||
def test_default_value(test_state):
|
def test_default_value(test_state):
|
||||||
"""Test that the default value of a var is correct.
|
"""Test that the default value of a var is correct.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user