简体   繁体   中英

EmberJS promises in controllers

I've been trying for hours to figure out why this isn't working, but I just can't seem to find a solution.

I'm trying to get data via REST, do a few things with the data (eg filter it) and then return the results.

This works perfectly if I just return the this.store.find('somthing') . As soon as I use then() - everything breaks.

App.SongController = Ember.ObjectController.extend({

  first: (function() {
    return this.second();
  }).property('first', '').volatile()


  second: (function() {
    var promise = Ember.Deferred.create();
    var data = [{ id: 1, name: 'hi' }];

    this.store.find('something').then(function (data) {
      // Do something with the data..

      // return the data
      promise.resolve(data);
    });

    return promise;
  }).property('second')

});

Errors in console:

Assertion failed: The value that #each loops over must be an Array. You passed <Ember.Deferred:ember350>
Uncaught TypeError: Object [object Object] has no method 'addArrayObserver'
Assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.
Uncaught Error: You cannot modify child views while in the inBuffer state 

It sounds like in your song template you are using an {{#each ...}} which tells ember you are iterating over some array, but it's finding something that isn't an array.

You can setup your SongController to be an ArrayController

App.SongController = Ember.ArrayController.extend()

and return the data from the model hook

App.SongRoute = Em.Route.extend({
   model: function(){
      return this.store.find('something');
   },
   setupController: function(controller, model){
     // and if your need to modify the data, it'll be loaded by this point
     model.blah = 123123;
     // then let ember finish off setting up the controller
     this._super(controller, model);
   }
});

If you really want it to be a computed property just return the promise from the find, it's an arrayproxy that will populate once it's resolved (so it will initially be 0, but once the server's responded it will grow).

second: function() {
  var promise = this.store.find('something').then(function (records) {
    records.objectAt(0).set('someValue', false);
  });

  return promise;
}.property('second')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM