Răsfoiți Sursa

chore: make for loops not the same

Jonathan Kelley 2 ani în urmă
părinte
comite
6c677e64da

+ 7 - 9
examples/dog_app.rs

@@ -4,6 +4,7 @@ use std::collections::HashMap;
 fn main() {
     dioxus_desktop::launch(|cx| {
         cx.render(rsx! {
+            h1 {"Loading...."}
             app_root {}
         })
     });
@@ -16,6 +17,7 @@ struct ListBreeds {
 
 async fn app_root(cx: Scope<'_>) -> Element {
     let breed = use_state(cx, || "deerhound".to_string());
+
     let breeds = use_future!(cx, || async move {
         reqwest::get("https://dog.ceo/api/breeds/list/all")
             .await
@@ -31,19 +33,15 @@ async fn app_root(cx: Scope<'_>) -> Element {
                 div { display: "flex",
                     ul { flex: "50%",
                         for cur_breed in breeds.message.keys().take(10) {
-                            rsx! {
-                                li { key: "{cur_breed}",
-                                    button {
-                                        onclick: move |_| breed.set(cur_breed.clone()),
-                                        "{cur_breed}"
-                                    }
+                            li { key: "{cur_breed}",
+                                button {
+                                    onclick: move |_| breed.set(cur_breed.clone()),
+                                    "{cur_breed}"
                                 }
                             }
                         }
                     }
-                    div { flex: "50%",
-                        breed_pic { breed: breed.to_string() }
-                    }
+                    div { flex: "50%", breed_pic { breed: breed.to_string() } }
                 }
             }
         }),

+ 2 - 2
examples/simple_list.rs

@@ -20,9 +20,9 @@ fn app(cx: Scope) -> Element {
             // Use optionals
             Some(rsx! { "Some" }),
 
-            // use a for loop
+            // use a for loop where the body itself is RSX
             for name in 0..10 {
-                rsx! { "{name}" }
+                div {"{name}"}
             }
 
             // Or even use an unterminated conditional

+ 10 - 11
packages/desktop/src/controller.rs

@@ -44,18 +44,17 @@ impl DesktopController {
                 .build()
                 .unwrap();
 
-            let mut dom = VirtualDom::new_with_props(root, props)
-                .with_root_context(DesktopContext::new(desktop_context_proxy));
-
-            {
-                let edits = dom.rebuild();
-                let mut queue = edit_queue.lock().unwrap();
-                queue.push(serde_json::to_string(&edits.template_mutations).unwrap());
-                queue.push(serde_json::to_string(&edits.edits).unwrap());
-                proxy.send_event(UserWindowEvent::Update).unwrap();
-            }
-
             runtime.block_on(async move {
+                let mut dom = VirtualDom::new_with_props(root, props)
+                    .with_root_context(DesktopContext::new(desktop_context_proxy));
+                {
+                    let edits = dom.rebuild();
+                    let mut queue = edit_queue.lock().unwrap();
+                    queue.push(serde_json::to_string(&edits.template_mutations).unwrap());
+                    queue.push(serde_json::to_string(&edits.edits).unwrap());
+                    proxy.send_event(UserWindowEvent::Update).unwrap();
+                }
+
                 loop {
                     tokio::select! {
                         _ = dom.wait_for_work() => {}

+ 14 - 7
packages/rsx/src/node.rs

@@ -3,9 +3,10 @@ use super::*;
 use proc_macro2::{Span, TokenStream as TokenStream2};
 use quote::{quote, ToTokens, TokenStreamExt};
 use syn::{
+    braced,
     parse::{Parse, ParseStream},
     spanned::Spanned,
-    token, Block, Expr, ExprIf, LitStr, Pat, Result,
+    token, Expr, ExprIf, LitStr, Pat, Result,
 };
 
 /*
@@ -98,14 +99,20 @@ impl Parse for BodyNode {
             let pat = stream.parse::<Pat>()?;
             let _i = stream.parse::<Token![in]>()?;
             let expr = stream.parse::<Box<Expr>>()?;
-            let body = stream.parse::<Block>()?;
+
+            let body;
+            braced!(body in stream);
+            let mut children = vec![];
+            while !body.is_empty() {
+                children.push(body.parse()?);
+            }
 
             return Ok(BodyNode::ForLoop(ForLoop {
                 for_token: _f,
                 pat,
                 in_token: _i,
                 expr,
-                body,
+                body: children,
             }));
         }
 
@@ -134,11 +141,11 @@ impl ToTokens for BodyNode {
                     pat, expr, body, ..
                 } = exp;
 
+                let renderer = TemplateRenderer { roots: &body };
+
                 tokens.append_all(quote! {
                      __cx.fragment_from_iter(
-                        (#expr).into_iter().map(|#pat| {
-                            #body
-                        })
+                        (#expr).into_iter().map(|#pat| { #renderer })
                      )
                 })
             }
@@ -213,7 +220,7 @@ pub struct ForLoop {
     pub pat: Pat,
     pub in_token: Token![in],
     pub expr: Box<Expr>,
-    pub body: Block,
+    pub body: Vec<BodyNode>,
 }
 
 fn is_if_chain_terminated(chain: &ExprIf) -> bool {