Reputation: 527
I have two controllers that have to communicate each other. The first reference to a video player and the second one to a timeline.
From the first one, I get the currentTime
of the video playback and I want to pass it to the second one that should move the time-bar as the video is playing.
I tried using the factory to share a variable called time
between controllers but this doesn't change during the time.
First Controller:
angular.module('videoCtrl', ['vjs.video'])
.controller('videoController', ['$scope', 'Timeline', function (scope, Timeline) {
scope.mediaToggle = {
sources: [
{
src: 'http://static.videogular.com/assets/videos/videogular.mp4',
type: 'video/mp4'
}
],
};
//listen for when the vjs-media object changes
scope.$on('vjsVideoReady', function (e, videoData) {
videoData.player.on('timeupdate', function () {
var time = this.currentTime();
Timeline.setTime(time); // setting the time on factory
})
});
}]);
Second Controller:
angular.module('timelineCtrl', ['mt.media-timeline'])
.controller('timelineController', function ($scope, Timeline) {
$scope.time = Timeline.getTime(); // here I'm trying to get the time
});
Factory:
.factory('Timeline', function(){
var timelines = [];
var time = null;
return {
getTime: function() {
return time;
},
setTime: function(_time) {
time = _time;
}
}
});
Upvotes: 3
Views: 713
Reputation: 798
Well as far as I can tell what're doing in the second controller is that you retrieve the value of time on instantiation of the controller. Of course further changes of the value in the service can't be picked up this way. To do that can use $scope.$watch
in the second controller:
angular.module('timelineCtrl', ['mt.media-timeline'])
.controller('timelineController', function ($scope, Timeline) {
$scope.time = Timeline.getTime(); //Set the time once so it's not undefined
$scope.$watch(
function() {return Timeline.getTime();},
function(newVal) {$scope.time = newVal;}
);
});
Angular will call the first function in every $digest
cycle(That's about at least every 10ms if I recall correctly) and will call the second function when a change has been detected. Detailed documentation for $watch
can be found here
This is one way to do it. You could also add a function to your $scope
(e.g. getTime()
), which should return the current time, and then call this function in the HTML template: {{getTime()}}
. Both ways pretty much work the same way, except that the second one leaves the 'dirty' work to angular(creating watchers and updating values)
Upvotes: 0
Reputation: 22323
time
appears to be a primitive, which means it is returned byVal rather than byRef. In other words, each call to getTime
will return the value that time
is currently set to, and calls to setTime
will change the value for future calls, but not for anything that already called it. This is a classic case of the angular rule, Always use a dot.
Try changing time
to an object instead:
.factory('Timeline', function() {
var timelines = [];
var time = {
value: null
};
return {
getTime: function() {
return time;
},
setTime: function(_time) {
time.value = _time;
}
}
});
In your HTML, use {{time.value}}
.
Upvotes: 5
Reputation: 157
Saving in $rootScope
instead of $scope
would give you the ability to access a variable across all your app and your controllers. But have in mind that creating a large number of $rootScope could affect your app's performance.
Do not forget to inject $rootScope
into the controller (like you did with $scope), so you can access it.
Upvotes: 0