[英]Rust / Yew Geolocation
我试图在 Yew 组件的create
函数中检索用户的纬度/经度,以便我可以做一些数学运算并将有用的决定传递给子组件。 我已经让 Yew 钩子“use_geolocation()”工作得很好,但它只在 function_component 中运行,而且似乎没有任何直接的方法可以在其他组件中使用该位置。
然后我发现了这个简洁的教程,它使用 wasm_bindgen 和 Seed::app::orders::Orders 来制作应用程序的“廉价克隆”,并调用 Javascript 函数。 绑定看起来像:
#[wasm_bindgen]
extern "C" {
type GeolocationCoordinates;
#[wasm_bindgen(method, getter)]
fn latitude(this: &GeolocationCoordinates) -> f64;
#[wasm_bindgen(method, getter)]
fn longitude(this: &GeolocationCoordinates) -> f64;
type GeolocationPosition;
#[wasm_bindgen(method, getter)]
fn coords(this: &GeolocationPosition) ->
GeolocationCoordinates;
}
还有获取地理位置的函数,将 Tor Hovland 教程中的代码块拼接在一起:
let (app, msg_mapper) = (orders.clone_app(), orders.msg_mapper());
let geo_callback = move |position: JsValue| {
let pos: GeolocationPosition = position.into();
let coords = pos.coords();
app.update(msg_mapper(Msg::Position(
coords.latitude(),
coords.longitude(),
)));
};
let geolocation = web_sys::window()
.expect("Unable to get browser window.")
.navigator()
.geolocation()
.expect("Unable to get geolocation.");
let geo_callback_function =
Closure::wrap(
Box::new(|pos| geo_callback(pos)) as Box<dyn Fn(JsValue)>
);
geolocation.get_current_position(
&geo_callback_function.as_ref().unchecked_ref()
).expect("Unable to get position");
geo_callback_function.forget();
我尝试了这条路线,但发现在我的 Cargo.toml 中添加行seed = "0.9.1"
会产生编译错误,这与 wasm_bindgen 中的闭包和种子中的某些内容之间的类型不匹配有关。 为了完整起见,包括在此处:
error[E0283]: type annotations needed for `Closure<T>`
--> /home/djmcmath/.cargo/registry/src/github.com-1ecc6299db9ec823/seed-
0.9.1/src/browser/service/routing.rs:87:9
|
87 | let closure = Closure::new(move |event: web_sys::Event| {
| ^^^^^^^
|
= note: cannot satisfy `_: WasmClosure`
note: required by a bound in `Closure::<T>::new`
--> /home/djmcmath/.cargo/registry/src/github.com-1ecc6299db9ec823/wasm-bindgen-
0.2.81/src/closure.rs:251:17
|
251 | T: ?Sized + WasmClosure,
| ^^^^^^^^^^^ required by this bound in `Closure::<T>::new`
help: consider giving `closure` an explicit type, where the type for type parameter
`T` is specified
|
87 | let closure: Closure<T> = Closure::new(move |event: web_sys::Event| {
| ++++++++++++
help: consider specifying the type argument in the function call
|
87 | let closure = Closure::new::<F>(move |event: web_sys::Event| {
| +++++
在将头撞在那块砖墙上一段时间后,我决定不使用 Seed,但我不知道另一种方法可以制作应用程序的“廉价克隆”以使生命周期正常运行。 没有它,我会在 geo_callback_function 上得到可预测的生命周期错误:
let geo_callback_function =
Closure::wrap(
Box::new(|pos: JsValue| geo_callback(pos)) as Box<dyn Fn(JsValue)>
);
错误信息:
error[E0597]: `geo_callback` does not live long enough
--> src/ferry_route.rs:213:37
|
213 | Box::new(|pos: JsValue| geo_callback(pos)) as Box<dyn Fn(JsValue)>
| ------------------------^^^^^^^^^^^^------
| | | |
| | | borrowed value does not live long enough
| | value captured here
| cast requires that `geo_callback` is borrowed for `'static`
...
221 | }
| - `geo_callback` dropped here while still borrowed
所以我在这一点上不知所措。 似乎获取用户的位置比这一切都简单。 我对任何使这些工作的路径持开放态度。 (工作定义:我可以在 Yew 组件的create
函数中获取用户的纬度/经度,这样我就可以做一些数学运算并将有用的决策传递给子组件。)
好的,我想我明白了。 或者至少,我有一些有用的东西。 我不确定这是最优雅的解决方案。 基本上,将 Seed 部分从函数中删除,然后从 JsValue 中提取坐标,如下所示:
fn geo_callback(position: JsValue) {
let pos = JsCast::unchecked_into::<GeolocationPosition>(position);
let coords = pos.coords();
log::info!(
"Latitude: {}. Longitude: {}.",
coords.latitude(),
coords.longitude()
);
};
在这一点上,我很确定我可以使用这些坐标并用它们做一些有用的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.