繁体   English   中英

Tauri:有什么方法可以访问常规结构中的 AppHandler 或 Window 或 state 管理的吗?

[英]Tauri: Is there some way to access AppHandler or Window in regular struct or state managed one?

我正在尝试使用 hotwatch 来监视文件夹以进行备份。

如果发生任何更改,预计会向前端发出一个事件以更新页面。

然后我发现它无法在常规结构中访问 AppHandle 或 Window。

我尝试过使用生命周期,但正如Tauri:accessing-an-apphandle-in-commands 所提到的,似乎没有办法维持足够长的生命周期。

pub struct MonitorHandler<'a> {
    pub watcher: Hotwatch;
    pub app_handler: Option<&'a AppHandle>
}

impl MonitorHandler<'_> {
    pub fn initialize_app_handler(&mut self, handler: AppHandle) {
        self.app_handler = Some(&handler);
    }
    
    pub fn append_target(path: &str) {
        self.watcher.watch(path, |event| {
            self.app_handler.emit_all("update");
        })
    }
}

// whitch shows error
89 |     pub fn initialize_app_handler(&mut self, handler: AppHandle) {
   |                                   --------- has type `&mut MonitorHandler<'1>`
90 |         self.app_handler = Some(&handler);
   |         ------------------------^^^^^^^^-
   |         |                       |
   |         |                       borrowed value does not live long enough
   |         assignment requires that `handler` is borrowed for `'1`
...
93 |     }
   |     - `handler` dropped here while still borrowed

我尝试在设置时添加应用程序句柄,但它仍然无法正常工作,并且存在相同的生命周期问题。

// main.rs
...
fn main() {
    let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
    let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor }));
    
    let context = tauri::generate_context!();
    tauri::Builder::default()
                .manage(store)
                .setup(|app| {
                       store.0.lock().unwrap().initialize_app_handler(app.app_handle());
                })
                .invoke_handler(tauri::generate_handler![
                    initialize_app_handler
                ])
                .run(context)
                .expect("error while running tauri application");
}

// which will occurs
   |
40 |   let store = MonitorHandler(Mutex::new(MonitorHandler {
   |       ----- move occurs because `store` has type `MonitorHandler<'_>`, which does not implement the `Copy` trait
...
51 |     .manage(store)
   |             ----- value moved here
52 |     .setup(|app| {
   |            ^^^^^^^^^^ value used here after move
53 |       store.0.lock().unwrap().initialize_app_handler(app.app_handle());
   |       ------- use occurs due to use in closure

我不熟悉 rust 和 tauri,那么在我的情况下,有什么方法可以访问 AppHandle 或 Window 吗? 或者我必须以另一种方式做到这一点?

这是我的原始代码

// handler.rs
// in this case, whether it's AppHandle or Window, the program will just stuck and not able to anything
pub struct MonitorHandler {
    pub watcher: Hotwatch;
    pub app_handler: Option<AppHandle>
}

impl MonitorHandler {
    pub fn initialize_app_handler(&mut self, handler: AppHandle) {
        self.app_handler = Some(handler.clone());
    }
}

pub struct MonitorHandler(pub Mutex<MonitorHandler>);

// main.rs
use hotwatch::Hotwatch;
use tauri::{ Manager, AppHandle };
use crate::handler::MonitorHandler;

#[tauri::command]
pub fn initialize_app_handler(monitor: State<MonitorHandler>, app_handler: AppHandle) -> bool {
    monitor.0.lock().unwrap().initialize_app_handler(app_handler);
    true
}

fn main() {
    let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
    let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor }));
    
    let context = tauri::generate_context!();
    tauri::Builder::default()
                .manage(store)
                .setup()
                .invoke_handler(tauri::generate_handler![
                    initialize_app_handler
                ])
                .run(context)
                .expect("error while running tauri application");
}

它卡住的原因是锁定操作导致 AppHandle 中的死锁,因为存储的结构被分配给 AppHandle 的实例。

如何解决这个问题很简单,感谢@FabianLars,这里是讨论后端是否有办法主动发出事件?

简而言之,只需初始化结构并在setup中管理它,就像这样

// handler.rs
pub struct MonitorHandler {
    pub watcher: Hotwatch;
    pub app_handler: AppHandle
}

impl MonitorHandler {
    pub fn do_something(&self) {
        // do something
        self.app_handler.emit_all("events", some_payload { ... });
    }
}

pub struct MonitorHandler(pub Mutex<MonitorHandler>);

// main.rs
use hotwatch::Hotwatch;
use tauri::{ Manager, AppHandle };
use crate::handler::MonitorHandler;

fn main() {
    // let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
    // let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor }));
    
    let context = tauri::generate_context!();
    tauri::Builder::default()
                .setup(move |app| {
                   let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
                   let struct_app_handle = app.handle().clone();
                   let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor, app_handler: struct_app_handle }));

                   app.manage(store);
                })
                .invoke_handler(tauri::generate_handler![
                    initialize_app_handler
                ])
                .run(context)
                .expect("error while running tauri application");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM