繁体   English   中英

Rust / Yew 地理位置

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

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