maomi
Introduction
Guide
Documents

Properties

Using properties in components

Components can contain several fields which are assignable through template attributes.

The properties should be wrapped with "Prop". The "Prop" type implements "Deref" so it can be dereferenced to the contained type.

#[component(Backend = DomBackend)]
struct MyChild {
template: template! {
<div> { format!("The content is {}", *self.content) } </div>
},
pub content: Prop<String>,
}
impl Component for MyChild {
fn new() -> Self {
Self {
template: Default::default(),
content: Prop::new("default".to_string()),
}
}
}
#[component(Backend = DomBackend)]
struct MyWebsite {
template: template! {
<MyChild content="from MyWebsite" />
}
}
impl Component for MyWebsite {
fn new() -> Self {
Self {
template: Default::default(),
}
}
}

Note that the property fields should be properly "pub" so that it can be assigned from templates in other rust modules.

Two-way properties

Common properties are one-way: the component receives the value from its user.

Sometimes it is required to be two-way, e.g. synchronize input values between components.

In these cases, "BindingProp" and "BindingValue" can be used. However, the changes of two-way values do not automatically triggering the template update. A task should be manually generated if the template update is required.

use maomi::prop::{BindingProp, BindingValue};
use maomi_dom::event::*;
#[component(Backend = DomBackend)]
struct MyChild {
template: template! {
<input value=&{ self.input_value } input=@value_changed() />
},
input_value: BindingValue<String>,
pub content: BindingProp<String>,
pub change: Event<()>,
}
impl Component for MyChild {
fn new() -> Self {
Self {
template: Default::default(),
input_value: Default::default(),
content: Default::default(),
change: Default::default(),
}
}
}
impl MyChild {
fn value_changed(this: ComponentEvent<Self, InputEvent>) {
this.task_with(|this, _| {
this.content.set(this.input_value.get());
this.change.trigger(&mut ());
});
}
}
#[component(Backend = DomBackend)]
struct MyWebsite {
template: template! {
<MyChild content=&{ self.content } change=@content_changed() />
<div> { self.content.get() } </div>
},
content: BindingValue<String>,
}
impl Component for MyWebsite {
fn new() -> Self {
Self {
template: Default::default(),
content: Default::default(),
}
}
}
impl MyWebsite {
fn content_changed(this: ComponentEvent<Self, ()>) {
this.task(|_| {});
}
}

Note that "BindingProp" and "BindingValue" do not implement "Deref" - use explicit getter functions to retrieve the value.