适当的地方放置这个功能?

时间:2015-07-21 17:13:08

标签: ember.js ember-cli

刚刚开始使用Ember.js并且已经有了一个愚蠢的问题!我想封装一些功能(将由几个不同的路由调用)。我不太确定把它放在哪里。

"程序"应该做到以下几点:

  1. 调出外部服务(目前是WP REST API,但将来可能是数据库)以获取一些数据。
  2. 如果数据是JSON对象的数组,则提取第一个对象。
  3. 对对象执行一些文本格式化,特别是在对象的HTML格式的 content 属性上调用htmlSafe()
  4. 这是我迄今为止所做的尝试:

    • 执行所有功能的助手。你似乎无法从帮助者那里回复承诺,所以这不起作用。
    • 执行数据检索的util(从路由&{39; s model()导入和调用)和执行数据格式化的帮助程序。这有效,但看起来很笨拙?
    • 一个组件,似乎没有一个好的位置来进行AJAX调用。

    这是一个绿地应用程序,所以我使用金丝雀进行一些未来验证。出于这个原因,我不想使用三重曲线。这是我的中间(工作)选项的代码:

    应用/路线/ tos.js:

    import Ember from 'ember';
    import wpJson from '../utils/wp-json';
    
    export default Ember.Route.extend({
      model() {
        return wpJson('terms-of-use');
      }
    });
    

    应用/ utils的/可湿性粉剂json.js:

    /* global Ember */
    export default function wpJson(slug) {
      var url = `/wp-json/posts?type[]=page&filter[name]=${slug}`;
      return Ember.$.getJSON(url).then(data => {
        return data.shift();
      });
    }
    

    应用/模板/ tos.hbs:

    {{html-safe model.content}}
    

    应用/助手/ HTML-safe.js:

    import Ember from 'ember';
    
    export function htmlSafe([html]) {
      return html.htmlSafe();
    }
    
    export default Ember.Helper.helper(htmlSafe);
    

    在某种完美的世界中,app/routes/tos.js将为空,app/templates/tos.hbs看起来更像是这样:

    {{wp-foo-bar slug='terms-of-use'}}
    

    提前感谢任何建议或反馈。

2 个答案:

答案 0 :(得分:1)

如何将所有逻辑放在组件本身中,如下所示:

//app/components/wp-foo-bar/component.js
import Ember from 'ember';

export default Ember.Component.extend({

  remoteData: null,

  loadingData: false,//maybe show spinner depending on this

  fetchRemoteData: function(slug){    
      var url = '/wp-json/posts?type[]=page&filter[name]='+slug;

      return new Ember.RSVP.Promise(function(resolve, reject){
        Ember.$.getJSON(url, function(data){
            resolve(data.shift());
        });
      });
  },

  didInsertElement: function(){
    var slug = this.get('slug');
    this.set('loadingData', true);
    this.fetchRemoteData(slug).then(function(data){
        this.set('remoteData', data);
        this.set('loadingData', false);            
    }.bind(this));
  }
});

该组件的模板如下所示:

{{html-safe remoteData}}

答案 1 :(得分:0)

这是我的最终解决方案,基于Deewandra的解决方案(我已标记为"正确")。主要区别在于ic-ajax的使用,Freenode的#emberjs中的人们出于各种原因强烈推荐。我还删除了html-safe帮助程序,并在组件内移动了htmlSafe()函数调用。

我唯一感到困惑的是一些间歇性的警告,我已经看到我没有在didInsertElement()钩子中设置属性。我想我会随着Ember.js 2.0的成熟而继续关注它,我对框架的理解也在不断提高。

应用/组件/ WP-GET-page.js:

import Ember from 'ember';
import ENV from '../config/environment';
import ajax from 'ic-ajax';

export default Ember.Component.extend({
  slug: null,
  isLoadingData: false,
  remoteData: null,

  didInsertElement() {
    const slug = this.get('slug');
    if (Ember.isEmpty(slug))
      throw new Error('slug not specified in wp-get-page call');

    this.set('isLoadingData', true);
    ajax(`${ENV.APP.WP_API_URL}/posts?type[]=page&filter[name]=${slug}`)
      .then(data => {
        if (Ember.isEmpty(data))
          throw new Error('no data from wp-json');

        if (Ember.isArray(data) && data.length === 1)
          data = data.shift();

        this.set('remoteData', {
          title: data.title,
          content: data.content.htmlSafe()
        });
      })
      .catch(() => {
        this.set('remoteData', {
          title: 'Sorry',
          content: 'Unable to retrieve page contents! Please try again later.'
        });
      })
      .finally(() => {
        this.set('isLoadingData', false);
      });
  }
});