Reputation: 506
I have some weird problem. Below app needs to do following things:
play selected song after clicking button with play_song function
when a song is finished, it should automatically start next song from playlist - if song is last one, it will start from the start
Everything seems to work fine, play_song button works correctly, when song is finished, it automatically start next one. But, the first time it starts another song, play_button function does not work anymore, it just does not update $scope.song, despite the fact that after checking it in console it does seem to be updated correctly. Please help as I cannot find the reason of described behaviour.
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>
Upvotes: 0
Views: 813
Reputation: 1933
It is a scope issue.
Be careful with scope inheritance. inheritance means that you'll get to access to properties from the parent scope, but everything you set will be in the current scope.
Therefore, childScope.song accesses parentScope.song, until childScope.song is assigned. And when childScope.song is assigned, parentScope.song remains unchanged.
The easiest solution here would be to put all your values inside an object.
$scope.data = {};
$scope.data.song = ...
[etc.]
See codepen below (don't mind the sample mp3s and the filter that was necessary to play mp3s from external sources).
http://codepen.io/jlowcs/pen/embgwV
Upvotes: 2