简体   繁体   中英

AngularJS: Communication between directives

I'm writing a directive which creates an mp3/audio player. The issue is that you can have many audio players in one page. What I would like to do is when one is playing and you start an other, that the one currently playing pauses. How can I achieve this with angular directives?

Thanks in advance!

Make a service that each directive uses and hold the state in there.

Something like this:

angular.module('MyPlayer' [])
.factory('playerState', function() {
    var players = [];
    return {
        registerPlayer: function(player) {
            players.add(player);
        },
        unregisterPlayer: function(player) {
            var i = players.indexOf(player);
            (i>-1) && players.splice(i,1);
        },
        stopAllPlayers: function() {
            for(var i=0;i<players.length;i++) {
                players[i].stop();
            }
        }
    }
})
.directive('player', function(playerState) {
    return {
        ...
        link: function(scope, elem, attr) {
            var player = {
                stop: function() {
                    /* logic to stop playing */
                },
                play = function(song) {
                    playerState.stopAllPlayers();
                    /* logic to start playing */
                }
            }

            playerState.registerPlayer(player);
            scope.$on("$destroy", function() {
                playerState.unregister(player);
            });

            scope.play = player.play;
            scope.stop = player.stop;

            ...
        }
    }
})

Just to make the answers complete, next to broadcasting events, and exposing a service, you can also use directive controllers. These controllers are set through the controller property of a directive definition object and are shared between directives that require the same controller. This means you can have one controller for all the media players, where you can implement the logic you mentioned. See the documentation on directives (search for controller: ) for more information.

I would recommend the service approach if you think there will be more consumers of the logic, or the directive controller approach if only the directives consume the logic. I would advise against broadcasting events on the root scope because of the uncoupled and global nature of it. Just my two cents! HTH

How are your directives setup? Please provide some code.

This depends on the scope of your directives, I'm going to assume a child scope. To communicate between the directives, when a user clicked to start a player, I would call a $scope.$parent.$broadcast() - or $rootScope.$broadcast() if the directives are in different controllers or using isolated scopes, but then you need to inject $rootScope into your directive - to send an event to all child scopes. My directives would be watching for this event using $on and any players that were playing would stop. After this broadcast the player clicked would start.

$broadcast() and $on() scope documentation

You can also do $rootScope.$broadcast events like playerStarted . This event can be subscribed by all directives and they can react to this event by stopping themselves. The one thing that you need to do would be pass in the data about the player which is starting so that the new player does not stop itself as it too would subscribe to such event.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM