table render error
Problem
Steps To Reproduce
Steps to reproduce the behavior:
- When I tried to render a table list data, only the first column was displayed, and every subsequent column was lost
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Environment:
- Dioxus version: [e.g. v0.4.0,
master] - Rust version: [e.g. 1.72.0,
nightly] - OS info: [e.g. MacOS]
- App platform: [e.g.
web]
Questionnaire
- [ ] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later
Uploading table.zip…
Can you fill out the rest of the issue template (especially the platform and renderer you are using) and provide the code that causes an error rendering tables? The information in the template helps us reproduce and fix the issue.
I have uploaded the entire project engineering
The entire project is as follows: Uploading table.zip…
The entire project is as follows:
[Uploading table.zip…](https://github.com/DioxusLabs/dioxus/issues/1712)
I think something may have gone wrong when you tried to create a link. That link leads to the current issue
Uploading table.zip…
directory structure :
/Cargo.toml:
[package]
name = "table"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dioxus = "0.4.3"
dioxus-web = "0.4.3"
dioxus_table ={ path = "./dioxus-table"}
/src/hotel.rs:
use dioxus::prelude::*;
use dioxus_table::*;
#[derive(TableData, Debug)]
#[table(tag = "table")]
pub struct Hotel {
#[table(title="标题a")]
pub a: String,
#[table(title="标题b")]
pub b: String
}
/src/main.rs:
pub mod hotel;
use dioxus::prelude::*;
use hotel::{Hotel, Table};
fn main() {
dioxus_web::launch(App)
}
fn App(cx: Scope) -> Element {
let state = use_state(cx, ||initHotel());
render!{
rsx!{
div {
"主键"
Table{
items: state.get()
}
}
}
}
}
fn initHotel() -> Vec<Hotel> {
vec![
Hotel{
a: "这是A1".to_string(),
b: "这还是B1呢".to_string()
},
Hotel{
a: "a2这是".to_string(),
b: "b2呢这还是".to_string()
}
]
}
/table-macro/Cargo.toml:
[package]
name = "table_macro"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro = true
[dependencies]
darling = "0.20.3"
heck = "0.4.1"
proc-macro2 = "1.0.70"
quote = "1.0.33"
syn = { version = "2.0.39", features = ["full" , "extra-traits"] }
/table-macro/src/lib.rs:
mod table;
use darling::FromDeriveInput;
use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;
#[proc_macro_derive(TableData, attributes(table))]
pub fn derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as syn::DeriveInput);
let data = table::TableDataDeriveInput::from_derive_input(&&input).expect("结构解析错误");
let data = quote!(#data);
data.into()
}
/table-macro/table.rs: use darling::{FromDeriveInput, util::{IdentString, self}, ast, FromField}; use heck::ToTitleCase; use quote::{ToTokens, quote}; use syn::spanned::Spanned;
#[derive(FromDeriveInput,Debug)] #[darling( attributes(table), supports(struct_named), forward_attrs(allow, doc, cfg) )] pub struct TableDataDeriveInput{ ident: syn::Ident, data: ast::Data<util::Ignored, TableDataField>,
#[darling(default)]
tag: Option<IdentString>,
#[darling(default)]
row: Option<IdentString>,
}
impl ToTokens for TableDataDeriveInput { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let TableDataDeriveInput {
ident,
tag,
data,
row
} = self;
let fields = data.as_ref().take_struct().expect("解析字段错误").fields;
let row_render = row.as_ref().map(|d| d.as_ident().clone())
.unwrap_or_else(||{
syn::Ident::new("Row", row.span())
});
let tag = tag.as_ref().map(|tag| {
let t = tag.as_ident();
quote!(
#t
)
}).unwrap_or(
quote!(table)
);
let mut titles = vec![];
let mut cells = vec![];
for field in fields.iter(){
let cell_rendel = field.cell.as_ref().map(|render| render.as_ident().clone())
.unwrap_or_else(|| {
syn::Ident::new("Cell", field.cell.span())
});
let name = field.ident.as_ref().expect("字段解析cuowu");
let name_str = name.to_string();
let title = if let Some(title) = &field.title {
title.clone()
} else {
name.to_string().to_title_case()
};
let title_render = field.title_render.as_ref().map(|head_render| head_render.as_ident().clone())
.unwrap_or_else(|| {
syn::Ident::new("title_render", field.title_render.span())
});
titles.push(quote!(
rsx!{
#title_render{
title: #title.clone()
}
}
));
cells.push(quote!(
rsx!{
#cell_rendel{
value: #name_str.clone()
}
}
));
}
tokens.extend(quote!(
#[inline_props]
pub fn Table<'a>(cx: Scope<'a>, items: &'a Vec<#ident>) -> Element {
cx.render(
rsx!{
#tag {
tr {
#(#titles)*
}
items.iter().map(|item| {
rsx!{
Row{
item: item,
#(#titles)*
}
}
})
}
}
)
}
))
}
}
#[derive(Debug, FromField)] #[darling(attributes(table))] struct TableDataField{ ident: Optionsyn::Ident,
#[darling(default)]
cell: Option<IdentString>,
#[darling(default)]
title: Option<String>,
#[darling(default)]
title_render:Option<IdentString>,
}
/dioxus-table/Cargo.toml: [package] name = "dioxus_table" version = "0.1.0" edition = "2021"
See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] dioxus = "0.4.3" gloo = "0.11.0" table_macro ={ path = "../table-macro"}
/dioxus-table/src/lib.rs: pub mod row;
pub mod cell_render;
pub mod head;
pub use row::; pub use cell_render::;
pub use table_macro::*;
pub use head::*;
/dioxus-table/src/row.rs: use dioxus::prelude::*;
#[derive(Props)] pub struct RowProps<'a, T:'a> { pub item:&'a T, pub children: Element<'a> }
pub fn Row<'a, T>(cx: Scope<'a, RowProps<'a, T>>) -> Element<'a> { cx.render( rsx!{ tr {
cx.props.children.iter().map(|child| rsx!{child})
}
}
)
}
/dioxus-table/src/head.rs: use dioxus::prelude::*; use std::fmt::Display; use gloo::console::console;
#[inline_props] pub fn title_render<T:PartialEq + Display>(cx: Scope, title:T) -> Element { console!("这是打印标题".to_string()); cx.render( rsx!{ th { "{title}" } } ) }
/dioxus-table/src/cell_render.rs: use dioxus::prelude::*; use std::fmt::Display;
#[inline_props] pub fn Cell<T:PartialEq + Display>(cx: Scope, value:T) -> Element { cx.render( rsx!{ td { "{value}" } } ) }
What is the reason for this problem?
What is the reason for this problem?
Can you provide a minimal example for this bug? The example should be one crate without any proc macros and preferably one file. I'm not trying to be difficult, but you understand the code that you uploaded better than me. If the issue is with rendering tables, you will be able to reproduce this with just a single component much quicker than me. This article does a pretty good job of explaining what MREs are and why they are useful https://antfu.me/posts/why-reproductions-are-required
If you think this issue is a problem with the macro code you copy-pasted into this issue, there are also places you can get help with that code: you could open a discussion asking for help or the post a message in the help channel of the Dioxus discord
I have uploaded the code to the warehouse: “https://gitee.com/y-s-b/dioxus-table-macro.git” Run dx serve to see, that all headers can be displayed, and only the first column is displayed in the content area
Dear technical experts, thank you for your hard work. When can this bug be fixed?