2015-03-19 2 views
0

У меня есть какая-то странная проблема. Ниже приложение должно сделать следующие вещи:Угловая переменная области не обновляется

  • играть выбранную песню после нажатия щелчка play_song функцией

  • , когда песня закончена, она должна автоматически начать следующую песню из плейлиста - если песня последний, он начнется с начала

Все работает нормально, кнопка play_song работает правильно, когда песня закончена, она автоматически запускается следующей. Но в первый раз, когда начинается другая песня, функция play_button больше не работает, она просто не обновляет $ scope.song, несмотря на то, что после проверки ее в консоли она, похоже, правильно обновляется. Пожалуйста, помогите, поскольку я не могу найти причину описанного поведения.

angular.module('playItApp', ['playItServices']) 

    .controller('songList', ['$scope', 'songsService', function($scope, songsService){ 
     $scope.playlist = songsService.query(); 
     $scope.song = null; 
     $scope.current_song = null; 
     $scope.play_song = function(index){ 
      $scope.song = $scope.playlist[index]; 
      $scope.current_song = index; 
     } 
    }]) 

    .directive('source', function(){ 
     return { 
      restrict: 'E', 
      scope: { 
       'src': '@' 
      }, 
      link: function(scope, element, attrs){ 
       scope.$watch('src', function(value){ 
        document.getElementById('track').load(); 
       }); 
      } 
     } 
    }) 

    .directive('audio', function(){ 
     return { 
      restrict: 'E', 
      link: function(scope, element, attrs){ 
       element[0].onended = function() { 
        if (scope.current_song + 1 < scope.playlist.length){ 
         scope.song = scope.playlist[scope.current_song+1]; 
         scope.current_song ++; 
        } else { 
         scope.song = scope.playlist[0]; 
         scope.current_song = 0; 
        } 
        scope.$apply(); 
       } 
      } 
     } 
    }); 


<h1>Playlist</h1> 
<ul> 
    <li ng-repeat="play in playlist"> 
     {{ play }} 
     <span class="fa fa-play" ng-click="play_song($index)"></span> 
    </li> 
</ul> 
<div ng-if="song"> 
    <h2>{{ song.title }}</h2> 
    <audio id="track" controls autoplay> 
     <source ng-src="{{ song.path }}" type="audio/mpeg"> 
    </audio> 
</div> 

ответ

2

Это проблема с объемом.

Будьте осторожны с наследованием сферы. Наследование означает, что вы получите доступ к свойствам из родительской области, но все, что вы установили, будет находиться в текущей области.

Поэтому childScope.song обращается к parentScope.song, пока не назначен childScope.song. И когда childScope.song назначен, parentScope.song остается неизменным.

Простейшим решением здесь было бы поставить все ваши значения внутри объекта.

$scope.data = {}; 
$scope.data.song = ... 
[etc.] 

См codepen ниже (не против образца mp3s и фильтр, который необходимо было играть mp3s из внешних источников).

http://codepen.io/jlowcs/pen/embgwV

+0

спасибо! Оно работает! К сожалению, я не уверен, что понимаю, почему это произошло. Это javascript или угловая конкретная проблема? Кроме того, есть ли другой способ решить эту проблему? Вы упомянули, что создание объекта-обертки является самым простым, но я был бы более чем счастлив узнать об этих трудных тоже, возможно, благодаря этому я лучше пойму эту проблему. – klis87

+0

Это общая угловая проблема, связанная с тем, как она создает области с использованием наследования прототипов. Менее простой способ и лучший способ решить эту проблему - использовать контроллер в вашей разметке (используя controllerAs) вместо области. Просто назначьте this.song вместо scope.song в своем контроллере и используйте список песен '' ng-controller = "как ctrl" 'и' '{{ctrl.song}}' 'в вашей разметке. Вам также придется передать некоторые из ваших переменных в качестве атрибутов (используя '' = '') в свою '' аудио'' директиву. – jlowcs

+0

Оказалось, что также можно исправить вышеуказанную проблему с помощью области. $ Parent.variable = значение в директиве, что вы думаете об этом решении? – klis87

Смежные вопросы