With rx now one can define a standalone parameter, without having to wrap it into a parameterized class.
However, this seems to have come at the cost of no longer being able to easily sync its value across multiple widgets.
In the example below, we define rx_param, and want to be able to set it in two ways.
Either by clicking the button, or by moving the slider. This is the best I could come up with:
from param import rx import panel as pn rx_param = rx(0) class A: def __init__(self, rx_param): self.rx_param = rx_param def __panel__(self): slider = pn.widgets.IntSlider(value=self.rx_param, start=0, end=10) return pn.Column(self.rx_param, pn.widgets.Button(name="Click me", on_click=lambda x: setattr(self.rx_param.rx, 'value', 10)), slider, pn.bind(lambda x: setattr(self.rx_param.rx, 'value', x), slider.param.value) # need this to set the rx_param ) pn.Column(A(rx_param=rx_param)).servable()
Note that although we can show the value of the parameter in the range slider, to update it we had to create a new variable for the slider so we could have a custom pn.bind that references that value.
For comparison, pre-reactive parameters, one would create a container object for the parameter. This adds a bit of boilerplate everywhere, but the actual display logic is simpler, as one can use .from_param directly for bi-directional communication.
from param import Parameterized, Integer import panel as pn class Container(Parameterized): value = Integer() class A: def __init__(self, container): self.container = container def __panel__(self): return pn.Column(self.container.param.value, pn.widgets.Button(name="Click me", on_click=lambda x: setattr(self.container, 'value', 10)), pn.widgets.IntSlider.from_param(self.container.param.value, start=0, end=10) ) pn.Column(A(container=Container())).servable()
Am I missing something? I would love it if there were a straightforward way to write to a reactive parameter.