如何在 Angular 工厂中将数据保存在 Scope 上

How to keep the data on Scope in an Angular factory

我正在学习 Ionic,并且正在编写教程。一切都很好,直到我创建了一个访问 web 服务的工厂。

当我访问范围内的变量时,它们没有定义,或者它们就像我初始化变量的方式一样。

这是代码

Controller.js

angular.module('songhop.controllers', ['ionic', 'songhop.services'])

/*Controller for the discover page*/
    .controller('DiscoverCtrl', function($scope, $timeout, User, Recommendations) {
      // get our first songs
      Recommendations.getNextSongs()
        .then(function(){
          $scope.currentSong = Recommendations.queue[0];
          console.log($scope.currentSong);
        });

      console.log(Recommendations.queue);
      console.log($scope.currentSong);
      // Fired when a song is favorited or skiped
      $scope.sendFeedback = function (bool){
    Recommendations.nextSong();

    // First add to favorites if they favorited
    if (bool) User.addSongToFavorites($scope.currentSong);

    $scope.currentSong.rated = bool;
    $scope.currentSong.hide = true;

    $timeout(function() {
      $scope.currentSong = Recommendations.queue[0];
    }, 250);
  };

})


/*
Controller for the favorites page
*/
.controller('FavoritesCtrl', function($scope, User) {
  // get the list of our favorites from  the user service
  $scope.favorites = User.favorites;

  $scope.removeSong = function(song, index) {
    User.removeSongFromFavorites(song, index);
  };
})

Service.js

  angular.module('songhop.services', []).factory('User', function() {

  var o = {
    favorites: []
  }


  o.addSongToFavorites = function(song){
    // Make sure there is a song to add
    if (!song) return false;

    // Add to favorites array
    o.favorites.unshift(song);
  }

  o.removeSongFromFavorites = function(song, index) {
    // make sure there is a song to remove
    if (!song) return false;

    // remove to favorites array
    o.favorites.splice(index, 1);
  }

  return o
})

.factory('Recommendations', function($http, SERVER) {
  var p = {
    queue: []
  };

  p.getNextSongs = function() {
    return $http({
      method: 'GET',
      url: SERVER.url + '/recommendations'
    }).success(function(data){
      // merge data into the queue
      p.queue = p.queue.concat(data);
    });
  };

  p.nextSong = function() {
    // pop the index 0 off
    p.queue.shift();

    // low on the queue? lets fill it up
    if (p.queue.length <= 3) {
      p.getNextSongs();
    }

  };
  return p;

})

在我为测试所做的 console.logs 行中,我在第一行中获得了正确的数据。第二个是[],第三个是undefined.

我不明白为什么

$scope.currentSong = Recommendations.queue[0];

没有将 $scope.currentSong 变量设置为应该的值,因为 $scope 变量应该是全局的,对吗?

第二个和第三个控制台日志不会return您提供任何数据,因为它们正在之前编辑的承诺return执行Recommendations.getNextSongs() 已解决。

第一个向您显示数据,因为您已将其正确放置在 then 块中,该块仅在 promise 解析时执行。 IE。当方法 Recommendations.getNextSongs() 完成时。

如果您像下面这样更新代码,每个控制台都会记录一些内容:

  Recommendations.getNextSongs()
        .then(function(){
          $scope.currentSong = Recommendations.queue[0];
             console.log($scope.currentSong);
             console.log(Recommendations.queue);
              console.log($scope.currentSong);
        });