Ember:处理来自组件中的ember-network promise的JSON响应

时间:2017-02-20 05:09:03

标签: ember.js

我正在尝试在组件中实现一个简单的自动提示。我正在测试fastboot,因此使用ember-network与我的API进行通信。我现在没有使用余烬数据。这是否是“余烬”的方式是一个不同的问题......我只是想让它发挥作用。

我的组件JS:

import Ember from 'ember';
import fetch from 'ember-network/fetch';

export default Ember.Component.extend({
    searchText: null,

    loadAutoComplete(query) {
        let suggestCall = 'http://my.api.com/suggest?s=' + query;
        return fetch(suggestCall).then(function(response) {
            return response.json();
        });     
    },

    searchResults: Ember.computed('searchText', function() {
        let searchText = this.get('searchText');
        if (!searchText) { return; }
        let searchRes = this.loadAutoComplete(searchText);
        return searchRes;
    })
});

在模板中:

{{input type="text" value=searchText placeholder="Search..."}}

{{ log "TEMPALTE RESULTS" searchResults }}
{{#each-in searchResults as |result value|}}
<li>{{result}} {{value}}</li>
{{/each-in}}

模板日志指令在我的控制台中输出:

console

数据在“建议”中,所以我知道fetch正在运行。我只是无法弄清楚如何实现它。我无法循环'_result'。我需要做什么来解析它并在模板中使用它?

2 个答案:

答案 0 :(得分:3)

从计算属性中返回承诺不仅仅是直接的,它有点棘手。

选项1。您可以在此用例中使用ember-concurrency插件。您可以查看auto complete feature explanation doc

您的组件代码,

import 'core-js/es7/array';

和你的组件hbs代码,

import Ember from 'ember';
import { task, timeout } from 'ember-concurrency';

export default Ember.Component.extend({
    searchText: null,

    searchResults: task(function*(str) {
        this.set('searchText', str);
        let url = `http://my.api.com/suggest?s=${str}`;
        let responseData = yield this.get('searchRequest').perform(url);
        return responseData;
    }).restartable(),
    searchRequest: task(function*(url) {
        let requestData;
        try {
            requestData = Ember.$.getJSON(url);
            let result = yield requestData.promise();
            return result;
        } finally {
            requestData.abort();
        }
    }).restartable(),
});

1选项。您可以返回DS.PromiseObject或DS.PromiseArray

<input type="text" value={{searchText}} onkeyup={{perform searchResults value="target.value"  }}>
<div> 
     {{#if searchResults.isIdle}}
        <ul>
            {{#each searchResults.lastSuccessful.value as |data| }}
            <li> {{data}} </li>
            {{else}}
             No result 
            {{/each}}
        </ul>
    {{else}}
        Loading...
    {{/if}} 
</div>

参考ember点火器文章 - The Guide to Promises in Computed Properties

答案 1 :(得分:0)

首先,IMO,从计算属性调用远程调用不是一个好习惯。您应该从输入组件/帮助器触发它。

{{input type="text" value=searchText placeholder="Search..." key-up=(action loadAutoComplete)}}

新的loadAutoComplete就像:

loadAutoComplete(query) {
    //check query is null or empty...
    let suggestCall = 'http://my.api.com/suggest?s=' + query;
    return fetch(suggestCall).then((response) => {
        this.set('searchResults', response.json());
    });     
},

您的searchResults将不再需要是计算属性。只是一个财产。