I'm just getting to grips with Angular, but passing around scope is getting the better of me when I try to abstract reusable components into separate modules.
I'm using an Angular Youtube module found here https://github.com/arnaudbreton/angular-youtube but it's woefully inadequate so I'm bolting on new functionality, namely support for the youtube API's Events.
First, here's the pertinent snippet from the third party module (abridged):
angular.module('youtube', ['ng'])
.service('youtubePlayerApi', ['$window', '$rootScope', '$log', function ($window, $rootScope, $log) {
var player = $rootScope.$new(true);
player.playerContainer = null;
player.create = function (attrs) {
player.playerId = attrs.id;
player.videoId = attrs.videoId;
return new YT.Player(this.playerId, {
videoId: attrs.videoId,
events:{
onStateChange: function(event){
switch(event.data){
case YT.PlayerState.PLAYING:
attrs.onEvent()
break;
}
}
}
});
};
player.load = function(){
this.playerContainer = player.create();
}
return player;
}])
.directive('youtubePlayer', ['youtubePlayerApi', function (youtubePlayerApi) {
return {
restrict:'A',
scope: {
id:'@',
videoId:'@',
onEvent:'&'
},
link: function (scope, element, attrs) {
youtubePlayerApi.create(attrs);
}
};
}]);
Then there's my own module:
var myapp = angular.module('myapp', ['youtube']);
myapp.controller('myAppCtrl', ['$scope', '$rootScope', '$location', '$log', 'youtubePlayerApi', function($scope, $rootScope, $location, $log, youtubePlayerApi) {
$scope.showVideo = function(){
$scope.youtubePlayer = youtubePlayerApi.load();
}
$scope.myEventHandler = function(){
alert('finished!')
}
}]);
and the associated template:
<div ng-app="myapp" id="ng-app">
<div ng-controller="myAppCtrl">
<div youtube-player id="ytplayer" video-id="0BWD5I6YrIo" on-event="myEventHandler()"></div>
</div>
</div>
As you'll see I'm struggling to connect the myeventhandler()
function of myAppCtrl
with the youtubeapi
module.
I'm also not sure I'm configuring the Isolate scope variables correctly as I've only ever seen it done when the scope values are being passed to a template, not a link function like this.
Any pointers on where i'm going wrong?
The isolate scope variables are configured correctly. attrs.onEvent()
does not work because attributes are strings rather than expressions. Still, the directive can pass the event handler to the service using its isolate scope variable:
link: function (scope, element, attrs) {
// using the isolate scope binding
youtubePlayerApi.create(attrs, scope.onEvent);
}
You would then modify create
to accept the new parameter:
player.create = function (attrs, handler) {
And also within create
, change attrs.onEvent()
to handler()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With