首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Yew中发送对子树的引用?

如何在Yew中发送对子树的引用?
EN

Stack Overflow用户
提问于 2022-06-05 20:46:26
回答 1查看 228关注 0票数 0

我有一个简单的Yew应用程序,在其中我画了一个二叉树,并渲染它的HTML。我希望将其保存在当前选择AppNode的模型( Leaf类型)中。(然后我会用不同的颜色)

我添加了一个Annot结构,并在NodeLeaf中添加了这个字段。现在,我在SelectTree类型中有一个Msg变体。我想为此添加一个参数,类似于SelectTree(&Tree),但这给了我一个“预期命名生命周期参数”错误。

我检查了示例,但它们都具有数组/向量中可表示的数据,因此传递索引就足够了,所以我没有从中学到多少东西。我能做些什么来传递消息中的引用?这有可能吗?如果这是不可能的,我可以使用unsafe,以及如何做到这一点?

下面是我现在的代码:

代码语言:javascript
复制
use yew::{html, Component, Context, Html};
use gloo::console::{self};

#[derive(Debug, Clone)]
pub struct Annot {
    is_selected: bool
}

impl Default for Annot {
    fn default() -> Annot { Annot { is_selected: false } }
}

#[derive(Debug, Clone)]
pub enum Tree {
    Leaf { ann: Annot },
    Node { ann: Annot, x: usize, l: Box<Tree>, r: Box<Tree> },
}

impl Tree {
    pub fn new() -> Tree {
        Tree::Leaf { ann: Default::default() } 
    }

    pub fn insert(&mut self, v : usize) -> () {
        match self {
            Tree::Leaf {ann} => {
                *self = Tree::Node { 
                    ann: Default::default(), 
                    x: v,
                    l: Box::new(Tree::Leaf { ann: Default::default() }),
                    r: Box::new(Tree::Leaf { ann: Default::default() })
                };
            }
            Tree::Node {ann, x, l, r} => {
                if v < *x { l.insert(v); } else if *x < v { r.insert(v); }
            }
        }
    }


    pub fn view(&self, ctx: &Context<App>) -> Html {
        match self {
            Tree::Leaf {ann} => {
                let cls = if ann.is_selected { "selected" } else { "" };
                html! { 
                    <li> 
                        <a class={cls} 
                            onclick={ctx.link().callback(|_| Msg::SelectTree)}>
                        </a> 
                    </li> 
                }
            }
            Tree::Node {ann, x, l, r} => {
                let cls = if ann.is_selected { "selected" } else { "" };
                html! {
                    <li>
                        <a class={cls} 
                            onclick={ctx.link().callback(|_| Msg::SelectTree)}>
                            { x }
                        </a>
                        <ul>
                            { l.view(ctx) }
                            { r.view(ctx) }
                        </ul>
                    </li>
                }
            }
        }
    }
}

pub enum Msg {
    SelectTree
}

pub struct App {
    tree: Tree
}

impl Component for App {
    type Message = Msg;
    type Properties = ();

    fn create(ctx: &Context<Self>) -> Self {
        let mut t = Tree::new();
        for i in [5,3,7,4,2,6,8] { t.insert(i); }
        Self { tree: t }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::SelectTree => {
                console::info!("Selected!");
                true
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> Html {
        html! { 
            <div class="tree"> 
            <ul> { self.tree.view(ctx) } </ul> 
            </div> 
        }
    }
}

fn main() {
    yew::start_app::<App>();
}

PS:我来自JavaScript和背景,相对来说我是Rust的初学者。我已经试着解决这个问题好几天了,所以我想我需要更明确的解释。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-08 00:58:59

在消息中发送Rc<RefCell<ATree>>并在模型中存储相同类型的消息是可行的。唯一的区别是您必须使用callback_once而不是callback,因为callback_once也接受特性FnOnce的回调。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72511003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档