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
});
}
我为此苦苦挣扎了一段时间,想不通。我拥有的是主控制器、工厂和服务,我正在尝试将数组从服务存储到控制器中的 $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
});
}