If you like data bindings and wish you could have more power like that in code,
then this library might be for you.
It’s based on a signals pattern, common in many front-end frameworks.
The implementation we wrote is based on solid-js,
one of the fastest javascript frameworks out there.
And is the next step in the evolution of anvil_labs.atomic
Example usage
from anvil_reactive.main import signal, render_effect
class Counter1(Counter1Template):
counter = signal(0)
@render_effect
def update_text(self):
self.counter_label.text = self.counter
def plus_button_click(self, **event_args):
self.counter += 1
def minus_button_click(self, **event_args):
self.counter -= 1
When the component is added to the screen:
- all render effects run
- in this example the
update_text()
method reads fromself.counter
which is a signal - later, when the value of this signal changes, render_effects that depend on the signal will re-run.
- These effects are batched to create performant updates.
Why?
It’s mostly to explore new patterns in anvil apps, and it’s quite a fun way to program.
You probably won’t want to use it in production, but we’ve created tagged versions so you can safely depend on a version without breakages.
It’s available as a third party dependency: N7KFE4YBWMGWJ5OX
Or by cloning from the github repo: GitHub - anvilistas/reactive: signals for anvil
Examples
Here is a set of examples you can clone:
Code Examples
from anvil_reactive.main import reactive_class, render_effect
@reactive_class
class Counter2(Counter2Template):
def __init__(self, **properties):
self.counter = 0 # all attributes in a reactive class are signals
@render_effect
def update_text(self):
self.counter_label.text = self.counter
def plus_button_click(self, **event_args):
self.counter += 1
def minus_button_click(self, **event_args):
self.counter -= 1
from anvil_reactive.main import bind, reactive_class
@reactive_class
class Counter3(Counter3Template):
def __init__(self, **properties):
self.counter = 0
bind(self.counter_label, "text", lambda: self.counter)
def plus_button_click(self, **event_args):
self.counter += 1
def minus_button_click(self, **event_args):
self.counter -= 1
from anvil.tables import app_tables
from anvil_reactive.main import render_effect, reactive_instance
counter_row = reactive_instance(app_tables.counter.get()) # 🤯
class Counter4(Counter4Template):
@render_effect
def update_text(self):
self.counter_label.text = counter_row["value"]
def plus_button_click(self, **event_args):
anvil.server.call("update_counter", counter_row, 1)
def minus_button_click(self, **event_args):
anvil.server.call("update_counter", counter_row, -1)
For questions, comments, suggestions, feel free to ask over at the github repo: