mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Add components interaction example (#951)
This add a small example of how to use agents in order to send messages between components.
This commit is contained in:
parent
a5e74e7d1d
commit
b534a4c83a
@ -23,4 +23,5 @@ members = [
|
||||
"timer",
|
||||
"todomvc",
|
||||
"two_apps",
|
||||
"pub_sub",
|
||||
]
|
||||
|
||||
11
examples/pub_sub/Cargo.toml
Normal file
11
examples/pub_sub/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "event_bus"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
web_logger = "0.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
yew = { path = "../.." }
|
||||
stdweb = "0.4.20"
|
||||
3
examples/pub_sub/README.md
Normal file
3
examples/pub_sub/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Sender receiver example
|
||||
Basic example that show how components that are not aware of each other can communicate
|
||||
using an agent.
|
||||
48
examples/pub_sub/src/event_bus.rs
Normal file
48
examples/pub_sub/src/event_bus.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Debug;
|
||||
use yew::worker::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum Request {
|
||||
EventBusMsg(String),
|
||||
}
|
||||
|
||||
pub struct EventBus {
|
||||
link: AgentLink<EventBus>,
|
||||
subscribers: HashSet<HandlerId>,
|
||||
}
|
||||
|
||||
impl Agent for EventBus {
|
||||
type Reach = Context;
|
||||
type Message = ();
|
||||
type Input = Request;
|
||||
type Output = String;
|
||||
|
||||
fn create(link: AgentLink<Self>) -> Self {
|
||||
EventBus {
|
||||
link,
|
||||
subscribers: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, _: Self::Message) {}
|
||||
|
||||
fn handle_input(&mut self, msg: Self::Input, _: HandlerId) {
|
||||
match msg {
|
||||
Request::EventBusMsg(s) => {
|
||||
for sub in self.subscribers.iter() {
|
||||
self.link.respond(*sub, s.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn connected(&mut self, id: HandlerId) {
|
||||
self.subscribers.insert(id);
|
||||
}
|
||||
|
||||
fn disconnected(&mut self, id: HandlerId) {
|
||||
self.subscribers.remove(&id);
|
||||
}
|
||||
}
|
||||
33
examples/pub_sub/src/lib.rs
Normal file
33
examples/pub_sub/src/lib.rs
Normal file
@ -0,0 +1,33 @@
|
||||
#![recursion_limit = "128"]
|
||||
|
||||
mod event_bus;
|
||||
mod subscriber;
|
||||
mod producer;
|
||||
|
||||
use subscriber::Subsciber;
|
||||
use producer::Producer;
|
||||
use yew::{html, Component, ComponentLink, Html, ShouldRender};
|
||||
|
||||
pub struct Model {}
|
||||
|
||||
impl Component for Model {
|
||||
type Message = ();
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||
Model {}
|
||||
}
|
||||
|
||||
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||
false
|
||||
}
|
||||
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
<Producer />
|
||||
<Subsciber />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
3
examples/pub_sub/src/main.rs
Normal file
3
examples/pub_sub/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
yew::start_app::<event_bus::Model>();
|
||||
}
|
||||
46
examples/pub_sub/src/producer.rs
Normal file
46
examples/pub_sub/src/producer.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::event_bus::EventBus;
|
||||
use yew::agent::Dispatched;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::event_bus::Request;
|
||||
use yew::agent::Dispatcher;
|
||||
|
||||
pub struct Producer {
|
||||
link: ComponentLink<Producer>,
|
||||
event_bus: Dispatcher<EventBus>,
|
||||
}
|
||||
|
||||
pub enum Msg {
|
||||
Clicked,
|
||||
}
|
||||
|
||||
impl Component for Producer {
|
||||
type Message = Msg;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
let event_bus = EventBus::dispatcher();
|
||||
|
||||
Producer { event_bus, link }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||
match msg {
|
||||
Msg::Clicked => {
|
||||
self.event_bus
|
||||
.send(Request::EventBusMsg(format!("Message receieved")));
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<button
|
||||
onclick=self.link.callback(|_| Msg::Clicked)
|
||||
>
|
||||
{"PUSH ME"}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
}
|
||||
39
examples/pub_sub/src/subscriber.rs
Normal file
39
examples/pub_sub/src/subscriber.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use super::event_bus::EventBus;
|
||||
use yew::agent::Bridged;
|
||||
use yew::{html, Bridge, Component, ComponentLink, Html, ShouldRender};
|
||||
|
||||
pub enum Msg {
|
||||
NewMessage(String),
|
||||
}
|
||||
|
||||
pub struct Subsciber {
|
||||
message: String,
|
||||
_producer: Box<dyn Bridge<EventBus>>,
|
||||
}
|
||||
|
||||
impl Component for Subsciber {
|
||||
type Message = Msg;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
let callback = link.callback(|s| Msg::NewMessage(s));
|
||||
let _producer = EventBus::bridge(callback);
|
||||
Subsciber {
|
||||
message: format!("No message yet"),
|
||||
_producer,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||
match msg {
|
||||
Msg::NewMessage(s) => self.message = s,
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<h1>{self.message.clone()}</h1>
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user