要素がクリックした時の走らせる処理の実装方法を見ていきます。
以下は最小のコンポーネントの書き方です。
use yew::prelude::*;
struct MyComponent {}
impl Component for MyComponent {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink) -> Self {
Self {}
}
fn update(&mut self, _message: Self::Message) -> ShouldRender {
true
}
fn view(&self) -> Html {
html! {
{"Hello Yew"}
}
}
} 修正が必要なのは以下の 3 点です。
関連型
Messageをちゃんと埋めるonclickハンドラを設定するupdateメソッドを発火する為のComponentLinkを扱えるようにする
今回はボタンをクリックする度on、offテキストが切り替わる感じのものを作ってみます。
関連型 Message をちゃんと埋める
以下のようなenum型で定義しておきます。
enum Message {
ButtonClick
}また、関連型の方も更新しておきます。
type Message = Message;onclick ハンドラを設定する
以下のことをする為にviewメソッドを更新します。
self.activeによるテキストの切り替えself.linkによるonclickハンドラの設定
と、その前に両方ともself経由なのでcreateとこのコンポーネント構造体の修正が必要です。
struct MyComponent {
link: ComponentLink,
active: bool,
} linkはcreateの第 2 引数として渡されイベントハンドラの設定に必要なものなので、もしイベントハンドラを使うのであれば構造体に持たせなければなりません。activeで適当にデフォルト値を設定します。
fn create(_: Self::Properties, link: ComponentLink) -> Self {
Self {
link,
active: false,
}
} viewに戻ります。textはifで適当に切り替えています。
そしてイベントハンドラの方ですがlinkのcallbackメソッドにクロージャーを渡しその中でMessageenumのどれかを返すようにします。
fn view(&self) -> Html {
let text = if self.active {
"on -> off"
} else {
"off -> on"
};
html! {
}
}このクロージャーが返した値は次にupdateメソッドの第 1 引数に渡されます。
fn update(&mut self, message: Self::Message) -> ShouldRender {
match message {
Message::ButtonClick => self.active = !self.active,
};
true
}Message::ButtonClickな時はactiveのboolを反対にしています。
updateメソッドでtrueを返すとコンポーネントの再レンダリングが走るので、それによってボタンの中のテキストの切り替えがされるハズです。
サンプル
nju33-com/get-started-yew-callback から動作確認が行えます。
親コンポーネントのコールバックを呼ぶ
onclickのようなプロパティを自作コンポーネントに渡すと、子から親を更新することができます。
これは例えば以下のような感じの構造になります。
struct Child {
onclick: Callback
}
// 但しそのまま子要素の例えば<button />のonclickに渡せるのではなく、一旦子コンポーネントでupdateメソッドを呼び、その中でコールバックのemitメソッドを呼び出す必要があります。
// こうすることで子コンポーネントのボタンがクリックされた時に、プロパティとして渡されたself.link.callback(closure)のclosureが実行されます。それにより親のupdateメソッドが呼ばれ、親コンポーネントの更新ができます。
ちなみにemitする時は 1 つ値を渡すことができます。そしてそれはclosureへ渡されるので、その値を見て返す値を変えたり、タプル構造体をupdateメソッドに渡したりといった事もできます。