You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/flow/advanced/signals.adoc
+255Lines changed: 255 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -405,3 +405,258 @@ Signal.effect(() -> {
405
405
String name = nameSignal.peek(); // The effect will not depend on nameSignal
406
406
});
407
407
----
408
+
409
+
== Signal Binding in Element
410
+
411
+
Various [classname]`com.vaadin.flow.dom.Element` features support signal binding, such as text, attributes, properties, [classname]`ClassList`, and [classname]`Style`. See <</flow/component-internals/element-api#,Element API>> for more details of those features.
412
+
413
+
Each feature works with same rules. When feature is bound to a signal, feature's value, like text content, is kept synchronized with the signal value while the element is in the attached state. When the element is in detached state, signal value changes have no effect. `null` signal unbinds the existing binding. While a signal is bound, any attempt to set the value manually in other way than through the signal, throws [classname]`BindingActiveException`. The same happens when trying to bind a new signal while one is already bound.
414
+
415
+
The following code serves as the base for the examples in the subsequent sections. It adds a button that increments a number signal by one and an empty span element:
416
+
[source,java]
417
+
----
418
+
public class SimpleCounter extends VerticalLayout {
419
+
420
+
private final NumberSignal counter =
421
+
SignalFactory.IN_MEMORY_SHARED.number("counter");
422
+
423
+
public SimpleCounter() {
424
+
Button button = new Button("Increment by one");
425
+
button.addClickListener(
426
+
click -> counter.incrementBy(1));
427
+
add(button);
428
+
429
+
Span span = new Span("");
430
+
add(span);
431
+
}
432
+
}
433
+
----
434
+
435
+
=== Text Binding
436
+
437
+
.`Element#bindText(Signal<String> signal)`
438
+
[source,java]
439
+
----
440
+
// NumberSignal's Double type has to be mapped to String.
441
+
Signal<String> signal = counter.map(value -> String.format("Clicked %.0f times", value));
442
+
443
+
span.getElement().bindText(signal);
444
+
// span's text content is now "Clicked 0 times"
445
+
----
446
+
.Basic functionality (same rules with all Element bindings)
447
+
[source,java]
448
+
----
449
+
// The following code demonstrates behavior step by step:
// DOM has "<span style='color: black; background: white'>"
606
+
607
+
color.value("red");
608
+
background.value("gray");
609
+
// DOM has "<span style='color: red; background: gray'>"
610
+
611
+
background.value(""); // same with null
612
+
// DOM has "<span style='color: red;'>"
613
+
614
+
span.getElement().getStyle().clear();
615
+
// DOM has "<span style>". Binding is also removed.
616
+
----
617
+
618
+
=== SignalPropertySupport helper
619
+
620
+
Not all component features delegate directly to the state in [classname]`com.vaadin.flow.dom.Element`. For those features, the [classname]`SignalPropertySupport` helper class ensures that state management behaves consistently with other Element bindings.
621
+
622
+
For example, a component can have a Java API to bind `Signal<String>` to modify the https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent[`textContent`] property of the element in the browser. `SignalPropertySupport#create(Component, SerializableConsumer<T>)` creates a new instance of `SignalPropertySupport` with `bind(Signal<T>)`, `get()`, and `set(T)` methods. The given consumer sets the `textContent` based on the value, as shown in the following example.
623
+
624
+
.MyComponent creation
625
+
[source,java]
626
+
----
627
+
// The following code demonstrates behavior step by step:
0 commit comments