ng -repeat повторяется, но пусто

#javascript #angularjs #soundcloud

#javascript #angularjs #soundcloud

Вопрос:

Я использую Soundcloud API для извлечения треков для запроса, введенного в поле поиска, например:

 $scope.tracks = [];

$scope.updateResults=function(song){
        if(song.length==0){
            $scope.tracks = [];
        }
        if(song.length>3){
            SC.get('/tracks', { q: song, license: 'cc-by-sa' }, function(tracks) {
                $scope.tracks = tracks;
                            //$scope.$apply() doesn't work either
            });
        }
    }
  

$scope.updateResults вызывается всякий раз, когда что-то вводится в панель поиска. Все это работает нормально. Я даже пробовал ведение $scope.tracks журнала, который представляет собой массив, и он заполняется дорожками, соответствующими результату поиска. Согласно ссылке на Soundcloud API, каждая дорожка имеет title свойство. Я проверил это, выполнив:

console.log($scope.tracks[0].title) , и я получил красивую строку с заголовком.

Теперь в моем ng-repeat , который написан так:

 <ul>
    <li ng-repeat="track in tracks">{{track.title}}</li>
</ul>
  

Я получаю несколько маркеров, но все они пусты. Другими словами {{track.title}} , не существует? Я проверил, что это допустимое свойство. Кроме того, я знаю, что $scope.tracks это заполняется, потому что действительно есть элементы списка, но все они пусты.

Спасибо за любую помощь!

РЕДАКТИРОВАТЬ: я провел некоторое исследование ng-repeat и узнал, что он следит за обновлениями, такими как .push() … все равно не должно объяснять это странное поведение, но это может помочь выявить проблему.

Комментарии:

1. Я подозреваю, что проблема не имеет ничего общего с. ngRepeat Попробуйте написать {{tracks[0].title}} outside the ngRepeat`, чтобы убедиться в этом. Как именно выглядит заголовок?

2. Работает для меня jsfiddle.net/moogs/4pmpY/2

3. Я опубликовал ответ, но у меня есть другой вопрос. Вы используете только одно представление? Отображаются ли дорожки на той же странице, что и окно поиска?

4. @hedgerh, да, они одинаковы ng-controller . Я попробую ваш ответ и дам вам знать. Спасибо!

5. @Moogs, спасибо, чувак. Я думаю, что разница, как заявил хеджер, заключается в том, что вы сделали HTTP-запрос самостоятельно, без SC API. Я попробую этот метод.

Ответ №1:

Это не будет самым техническим объяснением того, что происходит, поэтому я ценю все изменения. Поскольку Soundcloud Javascript SDK не использует $ http для получения дорожек, область видимости не знает, что ее нужно обновлять, когда SC.get возвращает дорожки. Другими словами, даже если $scope.tracks заполнен, он не знает, нужно ли обновлять представление. Я бы рекомендовал написать службу, которая обрабатывает все запросы GET / POST / PUT / DELETE в Soundcloud. Вот простой пример использования обратных вызовов:

 .factory('Soundcloud', function($http, $rootScope, $timeout, $q) {

  var request = function(method, path, params, callback) {
    params.client_id = sc.soundcloud.client_id;
    params.oauth_token = sc.soundcloud.access_token;

    $http({
      method: method,
      url: sc.soundcloud.api.host   path,
      params: params
    })
    .success(callback);
  };

  return {
    get: function(path, params, callback) {
      request('GET', path, params, callback);
    },

    put: function(path, params, callback) {
      request('PUT', path, params, callback);
    },

    post: function(path, params, callback) {
      request('POST', path, params, callback);
    },

    delete: function(path, params, callback) {
      request('DELETE', path, params, callback);
    }
  };
})
  

Как только вы вводите службу в свой контроллер, вы получаете такие треки:

 Soundcloud.get('/tracks', {limit: 5}, function(tracks) {
  $scope.tracks = tracks;
});
  

Просто настройте, где служба получает ваш client_id и oauth_token . Тогда путь — это любая конечная точка, которую вы хотите, а params — это любые параметры, которые вы хотите передать в SC.