如何在消息中发送对子树的引用

  • 本文关键字:引用 消息 rust yew
  • 更新时间 :
  • 英文 :


我有一个简单的紫杉应用程序,我在其中绘制二叉树并在HTML中渲染它。我想让它保存在模型(App类型)中,NodeLeaf当前被选中。(然后我会用不同的颜色)

我添加了一个Annot结构体,并将其添加为NodeLeaf中的字段。现在,我在Msg类型中有一个SelectTree变体。我想给它添加一个参数,比如SelectTree(&Tree)但这给了我一个预期的命名生命周期参数;错误。

我检查了例子,但他们都有数据表示在数组/向量,所以传递一个索引就足够了,所以我没有从他们那里学到很多。我怎么做才能在消息中传递引用?这可能吗?如果不可能,我可以使用unsafe做到这一点,以及如何?

下面是我现在的代码:
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的初学者。我已经试着解决这个问题好几天了,所以我想我需要更明确地解释一下。

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

相关内容

  • 没有找到相关文章

最新更新