2016-09-01 5 views
0

まず、計算されたプロパティで約束を得るのは望ましい方法ではないことが分かっています。しかし、私のセットアップでは、それは最適です。私は現在Ember 1.8.0-beta.1を互換性の目的で使用しています。Ember.js:計算されたプロパティで約束する

私は何を達成しようとしていることである:

weeknumbersChoicesWithColor: function() { 
    var weeknumberChoices = this.get('weeknumbersChoices'); 
    var yearnumber = this.get('yearnumber'); 
    var self = this; 

    var promises = []; 
    weeknumberChoices.forEach(function (weeknumber) { 
     var promise = self.store.findQuery('order', {'weeknumber': weeknumber, 'yearnumber': yearnumber}).then(function(orders){ 
      return orders.set('weeknumber', weeknumber); 
     }); 
     promises.push(promise); 
    }); 

    return Ember.RSVP.all(promises).then(function(result){ 

     result.forEach(function(weekOrders){ 
      // ... do something to get weeknumer and color 

      return { 
       weeknumber: weeknumber, 
       color: color 
      }; 
     }); 
    }); 
}.property('yearnumber', 'weeknumber'), 

で:

  • は私のコントローラで

それらのリンクを作る目的の色を含むすべてのweeknummersを取得します私のテンプレート:

{{#each weeknumbersChoicesWithColor}} 
    <li>{{#link-to 'orders' (query-params weeknumber=this.weeknumber)}}{{this.weeknumber}}{{/link-to}}</li> 
{{/each}} 

しかし、私のテンプレートはこのエラーを起こします:Uncaught Error: Assertion Failed: The value that #each loops over must be an Array. You passed {_id: 131, _label: undefined, _state: undefined, _result: undefined, _subscribers: } これはもちろん、約束がまだ完全ではないためです。私が{{#if weeknumbersChoicesWithColor.isFulfilled}}ブロックでそれらを包むときにも、それはあまりにも機能しません。

私は約束を返さないが、コントローラーの配列にEmber.run.laterというプロパティを設定すると動作しますが、それはかなりハッキングしているように見えますが、常に動作するとは限りません。

答えて

1

特に、EmberにはPromiseProxiesがあります。 Hereあなたが

{{#if myPromiseProxy.isFulfilled}} 
    // do stuff 
{{/if}} 

hereで、テンプレート内の適切な使用のためのプロキシに単一のオブジェクトをラップする方法を読んで、あなたが実際に必要ArrayProxyであることができます。テンプレートで次に

weeknumbersChoicesWithColor: function() { 
    var ArrayPromiseProxy = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin); 
    var weeknumberChoices = this.get('weeknumbersChoices'); 
    var yearnumber = this.get('yearnumber'); 
    var self = this; 

    var promises = []; 
    weeknumberChoices.forEach(function (weeknumber) { 
     var promise = self.store.findQuery('order', {'weeknumber': weeknumber, 'yearnumber': yearnumber}).then(function(orders){ 
      return orders.set('weeknumber', weeknumber); 
     }); 
     promises.push(promise); 
    }); 

    promises = Ember.RSVP.all(promises).then(function(result){ 

     result.forEach(function(weekOrders){ 
      // ... do something to get weeknumer and color 

      return { 
       weeknumber: weeknumber, 
       color: color 
      }; 
     }); 
    }); 
    return ArrayPromiseProxy.create({ 
     promise: promises 
    }); 
}.property('yearnumber', 'weeknumber'), 

:ここ

は、いくつかの関連するコードです

{{#if weeknumbersChoicesWithColor.isFulfilled}} 
    {{#each weeknumbersChoicesWithColor}} 
     <li>{{#link-to 'orders' (query-params weeknumber=this.weeknumber)}}{{this.weeknumber}}{{/link-to}}</li> 
    {{/each}} 
{{/if}} 

エンバーは実際にあなたがするたびにPromiseProxyMixinでArrayProxyを拡張する必要はありませんので、ご使用できArrayPromiseProxy実装を持っていますDS.PromiseArrayです。しかし、その主要なユースケースはモデルデータを扱うため、ember-data名前空間の下に置かれています。私は一般的に、自分のバージョンを使用しています。

このエラーが最初に発生する理由についての考えをクリアするには、RSVP.all(someArrayOfPromises)がオブジェクトであり配列ではないことを追加する必要があります。このオブジェクトは、resultプロパティを解決すると配列の値に設定しますが、それ自体の配列とはみなされません。プロキシは、RSVPオブジェクトの実行の実際の結果をラップし、現在の約束状態に応じて実行状態をチェックし、それぞれの表示ロジックで応答するための便利なプロパティを追加します。 ArrayProxyは、配列メソッドのいくつかをインスタンス化の瞬間にnullというcontentプロパティにマップし、RSVP.allが解決すると実際の配列になります。

1

map機能を使用する必要があります。

return result.map(function(weekOrders){ 
      // ... do something to get weeknumer and color 

      return { 
       weeknumber: weeknumber, 
       color: color 
      }; 
     }); 
+0

解決方法がありますが、テンプレートの結果をループすることはできません。これは、約束がまだpageloadで準備されていないためです。 '.isFulFilled'が正しく動作していないようですね?また、 '{{weeknumbersChoicesWithColor.isFulFilled}}'をテンプレートで直接印刷すると、真または偽を表示しません。 {{ログ}} '約束を守ると、APIコールの後にデータが正しく埋め込まれていることがわかります。私は何かを逃していますか? – DelphiLynx

+0

@DelphiLynx 'isFullFilled'の必要はありません。なぜそれを使いたいのですか? –

+0

テンプレートで次のように直接実行すると、 '{{#each weeknumbersChoicesWithColor}}'というメッセージが表示されます: 'Uncaught Error:アサーションに失敗しました:#eachループオーバーする値は配列でなければなりません。あなたは{_id:131、_label:未定義、_state:未定義、_result:未定義、_subscribers:}を渡しました。 – DelphiLynx

関連する問題