簡體   English   中英

使用返回的承諾數據

[英]Using returned promise data

我有類似的東西:

App.IndexController = Ember.ObjectController.extend({
   results : function(){

      return new Ember.RSVP.Promise(function(resolve, reject){

        Ember.$.getJSON('/search').then(function(res){
          console.log('response data is: ', res);
          resolve(res)
        })

      })

   }.property(),
  ...
})

// data
$.mockjax({
  url: '/search',
  responseText : {
    type: 'different people',
    res: [
      {name: 'charlie', age: '55'},
      {name: 'bobby', age: '19'},
      {name: 'raymond', age: '39'}
    ]
  }
})

我的jsbin

我實際上如何使用返回的數據? 當前, results返回一個承諾( this.get('results') ),所以我不能在hbs模板中使用它。 我需要將其轉換為對象然后返回該對象嗎?

回答問題

在內部,Ember使用PromiseProxyMixin對我們知道和喜愛的承諾進行魔術渲染。 這是與PromiseProxy一起使用的更新的JSBin:

http://emberjs.jsbin.com/danazu/edit?html,js,output

您的results屬性變為:

results: Ember.computed.promise(function(resolve, reject) {
  Ember.$.getJSON('/search').then(function(res) {
    console.log('response data is: ', res);
    return resolve(res);
  });
})

但是我不建議這樣做。 看一下這個討論線程,以獲取有關為什么您可能不想這樣做的一些信息。 簡而言之,處理所有不同的承諾狀態將很笨拙。

尋找更好的方法

路由器是處理AJAX請求承諾的理想場所。 afterModel某些原因,您不只是將數據加載到modelafterModel掛鈎中的路由器中。 您可以創建另一個嵌套資源來表示這些搜索結果,然后僅link-to該資源嗎?

在您的路由器中:

Router.map(function() {
  this.resource('search', { path: '/search/:term' });
});

App.PeopleRoute = Ember.Route.extend({
  model: function(params) {
    return Ember.$.getJSON('/search?term=' + params.term);
  }
});

如果那至少不起作用,您可以:

  1. 想要搜索結果時發送action
  2. 在控制器中處理AJAX請求
  3. 解決results ,在控制器上設置results

我使用ic ajax可以輕松實現promise。 我目前不使用Ember數據,因此我在ic ajax上為自己編寫了一個不錯的rest客戶端,以輕松獲取/發布/輸入網址:

rsvpAjax: function(url,method, data){
      var headers = {};

      // build request
      var opts = {};
      var defaultOpts = {
        type: method,
        headers: headers,
        data: JSON.stringify(data),
        dataType: 'json',
        xhrFields: {
          withCredentials: true
        }
      };
      return ajax.request(url, $.extend({}, defaultOpts, opts));
}

然后我有方法:

getAsync: function(url){
      return this.rsvpAjax(url, "GET");
}

然后在facade / helper類的其他地方使用它:

import objFactory from 'appname/models/obj';
...
...
foo: function(){
        //get your rest client somehow
        var apiFacade = this.getRestClient();
        return restClient.getAsync('url_string').then(function(response){
            //targets some part of the response - here its an array of 
            var data = response.data;
            return data.map(function(obj){
                return objFactory.create(obj);
            });
        });
}

foo返回一個Ember對象數組。 我導入的objFactory只是一個Ember.Object類。 傳遞給創建的obj通常與所述Ember.Object中的屬性進行一對一匹配。 使用初始化程序,我將此對象注入到每個路由中:

import someFacade from "app/facades/facade";

export default {
    name: 'someFacade',

        initialize: function(container, app) {
        //a singleton by default
        container.register('facades:someFacade',someFacade);
        app.inject('route', 'someFacade', 'facades:someFacade');
    }
};

由於DI,我的任何路線都可以使用此立面而無需導入它。

//Ember blocks
model: function(){
    return this.someFacade.foo();
}

要么:

setupController(controller, model){
    //set controller prop on return of resolved val
    this.someFacade.foo().then(function(foosReslovedVal){
        controller.set('someProp', foosResolvedVal);
    });   
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM