Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you call your module's controller function from an entirely separate module's controller?

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?

like image 484
xcession Avatar asked Nov 03 '22 21:11

xcession


1 Answers

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()

like image 170
Dan Avatar answered Nov 12 '22 14:11

Dan