首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写具有外部依赖关系的服务

编写具有外部依赖关系的服务
EN

Stack Overflow用户
提问于 2016-03-09 12:37:26
回答 2查看 209关注 0票数 1

我正在编写一个服务来包装我的应用程序需要的几个调用。

类似于:

代码语言:javascript
复制
import Ember from 'ember';

export default Ember.Service.extend({
  googleAutocompleteService: null,
  placePredictions(query) {
    var self = this;
    return new Ember.RSVP.Promise(function(resolve, reject){
      ...
      self.get('googleAutocompleteService').getPlacePredictions(request, callback);
    });
  },
  init(){
    this._super(...arguments);
    this.set('googleAutocompleteService',
             new google.maps.places.AutocompleteService());
  },
});

现在,我显然需要加载Google。目前,我已经将它包含在我的index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
  <head>
    ...
  </head>
  <body>
    {{content-for 'body'}}

    <script src="https://maps.googleapis.com/maps/api/js?key=...&libraries=places" async defer></script>

    ...

    {{content-for 'body-footer'}}
  </body>
</html>

偶尔,我的服务会在初始化映射API之前加载,从而导致错误。我可以简单地从标记中删除async defer并同步加载它,但是必须有一种方法让我的服务将外部库作为依赖项加载?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-09 14:26:42

您可以将google服务设置为计算承诺属性。这是一个干净的方式,以确保它将是懒惰负载,只有一次。

npm i ember-inject-script --save-dev

代码语言:javascript
复制
import Ember from 'ember';
import injectScript from 'ember-inject-script';

const {
  getOwner,
  computed,
  PromiseProxyMixin
  Service
} = Ember;

const ObjectPromiseProxy = ObjectProxy.extend(PromiseProxyMixin);
const GOOGLE_PLACES_SCRIPT_URL = 'https://maps.googleapis.com/maps/api/js?key=...&libraries=places';

export default Service.extend({
  googleAutocompleteService: computed(function() {
    return ObjectPromiseProxy.create(getOwner(this).ownerInjection(), {
      promise: injectScript(GOOGLE_PLACES_SCRIPT_URL).then(() => {
        return new window.google.maps.places.AutocompleteService();
      })
    });
  }),
  placePredictions(query) {
    return this.get('googleAutocompleteService').then((resolvedService) => {
      //...
      resolvedService.getPlacePredictions( /* ... */ );
      //...
      return {}; // return whatever you want the promise to resolve;
    });
  }
});
票数 4
EN

Stack Overflow用户

发布于 2016-03-09 14:15:36

我处理这一问题的一种方法是在组件或路由生命周期挂钩中。

如果在特定路由上使用映射,则可以在beforeModel/afterModel挂钩中添加一个afterModel

代码语言:javascript
复制
beforeModel() {
   return Ember.$.getScript('https://maps.googleapis.com/maps/api/js?key=...&libraries=places');
}

现在,我不完全确定这是否能解决服务中的问题。

如果您的所有映射工作都包含在一个组件中,那么您可以使用didInitAttrs()钩子尝试相同的操作。

在服务init()钩子中也值得一试,但我不确定是否有一种方法可以让它等待承诺的实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35891816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档