Commit 0cd2174
Update function for components referenced by id
Changed files (4)
modifiedexamples/counter-component/src/counter.rsmodifiedexamples/counter-component/src/main_component.rsmodifiedsrc/lib.rsmodifiedsrc/prelude.rs
Diff
@@ -5,7 +5,7 @@ pub struct Counter { value: i32, } -impl Component for Counter {+impl Counter { fn connected(&mut self, element: HtmlElement) { self.render(&element); }@@ -38,19 +38,11 @@ impl Counter { return; } - let component_id = element.get_attribute("componentid");-- if component_id.is_none() {- log!("No component_id.");- return;- }-- let id = component_id.unwrap();-+ let component_id = self.get_component_id(); let content = html! {{ <p> Count: $(count.unwrap())- <button onclick="increment('$id');">Increment</button>+ <button onclick="increment('$component_id');">Increment</button> </p> }}; @@ -60,39 +52,34 @@ impl Counter { #[callback(increment)] pub fn increment(id: String) {- let element = get_component_element(id.as_str());-- if element.is_none() {- error!("Element not found for id", id);- return;- }+ log!("increment");+ // id is a String from the callback; update_component accepts AsRef<str>.+ update_component(id, |component: &mut Counter, element: &HtmlElement| {+ log!("update_component", component.get_component_id());+ increment_component(component, element);+ });+} - let html_element = element.unwrap();- let count_attribute = html_element.get_attribute("count");+fn increment_component(component: &mut Counter, element: &HtmlElement) {+ let count_attribute = element.get_attribute("count"); if count_attribute.is_none() {- error!("Attribute count not found for id", id);+ error!("Attribute 'count' not found for element"); return; } - let count = count_attribute.unwrap().parse::<i32>();-- if !count.is_ok() {+ let count_res = count_attribute.unwrap().parse::<i32>();+ if count_res.is_err() { error!("Count is not an integer."); return; } - let mut current_count = count.unwrap();- current_count += 1;+ let new_count = count_res.unwrap() + 1; - if let Some(counter_arc) = get_component::<Counter>(id.as_str()) {- let mut counter = counter_arc.lock().unwrap();- counter.value = current_count;- counter.render(&html_element);- } else {- error!("Component not found for id", id);- return;- }+ component.value = new_count;+ element.set_attribute("count", new_count.to_string().as_str());++ log!("new count", new_count); - let _ = html_element.set_attribute("count", current_count.to_string().as_str());+ component.render(element); }@@ -5,7 +5,7 @@ pub struct Main { message: Option<String>, } -impl Component for Main {+impl Main { fn connected(&mut self, element: HtmlElement) { self.render(element); }@@ -4,7 +4,7 @@ #![doc = include_str!("../README.md")] use gloo_console::{error, log};-use wasm_bindgen::{JsCast, JsValue};+use wasm_bindgen::JsCast; use web_sys::{Element, HtmlDocument, HtmlElement, HtmlInputElement, NodeList}; pub mod prelude;@@ -339,6 +339,8 @@ pub trait Component { ) { log!("Attribute changed but no update handler for ", name); }++ fn get_component_id(&self) -> String; } pub fn get_component_element(id: &str) -> Option<HtmlElement> {@@ -373,3 +375,38 @@ pub fn get_component<T: ComponentStorage + 'static>( let map = store_opt.as_ref().unwrap(); map.get(id).cloned() }++pub fn update_component<F, T, S>(id: S, callback: F)+where+ S: AsRef<str>,+ F: Fn(&mut T, &HtmlElement),+ T: ComponentStorage + 'static,+{+ let id_ref = id.as_ref();+ let element_opt = get_component_element(id_ref);++ if element_opt.is_none() {+ error!("Element not found for id", id_ref);+ return;+ }++ let element = element_opt.unwrap();++ let component_opt = get_component::<T>(id_ref);++ if component_opt.is_none() {+ error!("Component not found for id", id_ref);+ return;+ }++ let component_arc = component_opt.unwrap();+ match component_arc.try_lock() {+ Ok(mut component) => {+ callback(&mut component, &element);+ }+ Err(_) => {+ error!("Can't lock component for id", id_ref);+ return;+ }+ }+}@@ -2,7 +2,7 @@ pub use crate::{ CallbackRegistration, Component, ComponentStorage, Error, InitComponentFn, InitFn, Result, get_callback, get_component, get_component_element, get_cookie_value, get_element, get_elements, get_value, init_callbacks, inner_html, inner_text, try_get_value, try_inner_html,- try_inner_text,+ try_inner_text, update_component, }; pub use gloo::console::error;