【问题标题】:How to load an Ember Component in application template before everything else?如何先在应用程序模板中加载 Ember 组件?
【发布时间】:2015-01-14 14:19:55
【问题描述】:

我目前正在构建一个小的 Ember 应用程序,它允许用户通过地图访问报纸上的旅游小贴士文章。因此,我构建了一个小 Leaflet 组件,用于显示应用程序可以与之交互的地图(动画到坐标、更改缩放等)。

地图是应用程序的核心元素,始终可见。所以我将组件放入应用程序模板中。它填满了整个背景并且定位固定。所有子路线都在“悬停”在地图上的div.content 中呈现。

…
<div class="app-body">
  <script type="text/x-handlebars" data-template-name="application" id="application">
  <div class="map-container">
  {{leaflet-map
        id="map"
        class="map"}}
  </div>
  <div class="content">
    {{outlet}}
  </div>
  </script>
</div>
…

由于我必须在开头预加载所有文章及其坐标(以放置所有标记),因此我将预加载添加到 IndexRoute 的 beforeModel 挂钩中,并通过 @987654323 从存储在路由的模型挂钩中获取数据@。

这个想法是后台的地图在开始时加载,并且在应用程序开始预加载文章时已经可见。我认为如果将它直接放入应用程序模板中就会出现这种情况。显然不是。地图在预加载完成后加载并显示,我不知道如何更改它。如果有人能提示我正确的方向,那就太好了。

更新 控制台日志显示该组件,尽管它是应用程序模板的一部分,但在其他所有操作之后都在最后进行了初始化。不知道为什么。

…
[✓] template:index ............................................. template at index
[ ] view:default ............................................... undefined.DefaultView
Transition #0: TRANSITION COMPLETE.
[ ] helper:leaflet-map ......................................... undefined.LeafletMapHelper
[ ] component-lookup:main ...................................... undefined.MainComponentLookup
[✓] template:components/leaflet-map ............................ template at components/leaflet-map
[✓] component:leaflet-map ...................................... undefined.LeafletMapComponent 

【问题讨论】:

  • 为什么要在这里拆分为beforeModelmodel?在我看来,您可以摆脱beforeModel 中的代码,然后只需将model 挂钩设置为return this.store.find('article')
  • 没那么简单。我必须使用的 API 迫使我循环浏览几页文章以获取所有内容。所以——我没有在适配器中实现这个——我做了一个单独的递归预加载函数,它返回一个 Promise,它解析为下一个返回它的 Promise 的调用,依此类推。最后,所有文章都被推送到商店。为了保持整洁,我将预加载分开并放在 beforeModel 钩子中。

标签: javascript ember.js components leaflet


【解决方案1】:

在模型解析之前不会渲染模板(地图)。如果钩子 beforeModelafterModel 返回承诺,模型将不会被解析。

您将地图放在应用程序模板中并从索引路由中获取文章,很好。问题是返回承诺的嵌套路由也阻塞了它们的父级。应用程序转换被阻止,直到索引转换解决。

所以在您等待的时候,您可以使用Loading / Error Substates 。在这种情况下,加载状态。

示例:http://emberjs.jsbin.com/sihedi/1/edit?html,js,output

在加载状态下,您允许部分渲染,当嵌套路由完成其转换时,加载模板将替换为您的应用所做的任何事情。

【讨论】:

  • 这正是我所做的。正如您在我的代码 sn-p 中看到的那样,该组件被放置在应用程序模板中。然后从索引路由预加载和获取文章。
  • 对,我改进了答案并提供了一个例子。
【解决方案2】:

当您加载您的应用程序时,它要做的第一件事就是处理App.ApplicationRoute。它将通过它的模型钩子,设置控制器,并渲染模板。之后,它会对App.IndexRoute 执行相同的操作(注意:索引路由总是在父路由下隐式创建),并将其模板渲染到您在上面定义的{{outlet}} 中。

因此,在我看来,您应该将找到标记的代码放入App.IndexRoute

但是,您可能仍有问题。如果您的{{leaflet-map}} 组件是必须异步加载的东西(这似乎是http://leafletjs.com/reference.html 的情况),则在组件在DOM 中呈现后,地图本身不会立即出现。在这种情况下,您应该监听表示地图已加载的事件,然后触发可在路线层处理的操作以加载标记。

【讨论】:

  • 是的,文章(以及标记)是从 IndexRoute 加载的。我对异步加载的地图有同样的想法。当我从 IndexRoute 加载大约 140 篇文章时,它需要一点时间,并且地图会出现在 预加载完成之后。所以地图加载时间过长似乎不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 2018-06-19
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多