[英]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.