Angular 在控制器调用时填充和 return 服务变量

Angular fill and return service var on controller call

我为此苦苦挣扎了一段时间,想不通。我拥有的是主控制器、工厂和服务,我正在尝试将数组从服务存储到控制器中的 $scope。在查看项目时点击控制器中的这个功能被触发:

$scope.getSongsInPlaylist = function()
                    {
                        var playlistId = this.item.idPlayliste;                        
                        $scope.Mp3Files = songInPlaylistFactory.getSongsForPlaylist(playlistId);

                    }

工作正常,此函数从视图中检索项目并将该项目的 ID 发送到服务中。 比起我的服务,我有这样的代码:

var Songs = [ ];
    this.getSongsForPlaylist = function (id)
                        {
                             for (var i = 0; i < SongIsOnPlaylist.length; i++)
                             {
                                 if(SongIsOnPlaylist[i].idPlayliste == id)
                                 {                                 
                                     dataFactory.getDataById(mp3fileUrl, SongIsOnPlaylist[i].idPjesme)
                                     .success(function (data) {
                                         Songs.push(data);
                                         alert(Songs[0].naslovPjesme);//Alert one                              
                                     });                           
                                 }                            
                             }
                             alert(Songs[0]);// Alert two
                             return Songs;                         
                         }

dataFactory 是我的工厂,它在后端与 api 通信,它也可以工作。 var Songs 定义为:var Songs = [ ]; SongIsOnPlaylist 中填充了数据。

当我触发这个时,警报二给我未定义,警报一给我歌曲中第一首歌的名字。这意味着 var Songs 充满了数据,但是当我想让它 return 来控制它的空 ...

我是不是做错了什么,希望得到任何帮助?

首先,您的 dataFactory.getDataById 似乎是异步调用。 因此,实际发生的是你 returns 一个空的 Songs 数组,然后当你所有的异步调用 returns.

为了解决这个问题,我建议使用像 bluebird 这样的 Promise 库来做这样的事情:

// note that now your service will return a promise
this.getSongsForPlaylist = function (id) {
  return new Promise(function(resolve, reject) {

    var promises = [];
    // here in your loop just populate an array with your promises
    for (var i = 0; i < SongIsOnPlaylist.length; i++){
      if(SongIsOnPlaylist[i].idPlayliste == id){                                 
        promises.push( dataFactory.getDataById(mp3fileUrl, SongIsOnPlaylist[i].idPjesme) )
      }                            
    }
    // now use the library to resolve all promises  
    Promise.all(promises).then( function (results) {
      //HERE YOU WILL GET the results off all your async calls
      // parse the results 
      // prepare the array with songs 
      // and call
      resolve(Songs); 
    });
  });

}

那么您将像这样使用该服务:

$scope.getSongsInPlaylist = function() {
  var playlistId = this.item.idPlayliste;                        
  songInPlaylistFactory.getSongsForPlaylist(playlistId)
  .then(function(Songs){
    $scope.Mp3Files = Songs
  })
  .error(function(err){
    //here handle any error
  });
}