0

I have a main controller in which i want to emit/ broadcast an event

main controller

.controller('gameCtrl', function(){
function moveToTileBy(moves)
  {
      var numberOfTiles = ctlr.board.tiles.length,
          player = getCurrentPlayer(),
          currentTileNumber = player.currentPositionTileNumber;

      if((moves + currentTileNumber) > numberOfTiles)
      {
        // alert player not enough moves
        return nextTurn();
      }
    // create a drag and drop
    $scope.$emit('movePlayer', currentTileNumber);
    $scope.$emit('activateTile', moves + currentTileNumber);
  }
})

I also have a directive on an ng-repeatitems, each item has an isolated scope whose only connection to the main controller is the scope's model

directive

.directive('phTile', ['$rootScope', 'Drake', function ($rootScope, Drake) {
return {
    restrict: 'A',
    scope: {
      tile: '@ngModel'
    },
    link: function (scope, element, attr) {
        var elem = element[0];
        console.log(scope.tile);
        $rootScope.$on('movePlayer', function(){
          console.log('root link move player ', arguments);
        });

        scope.$on('movePlayer', function(){ console.log('link scope move player', arguments);})
    }
};

html

<div ng-controller="gameCtrl as ctlr">
<div ng-repeat="(i, tile) in ctlr.board.tiles" class="w3-col tile tile-{{tile.number}}" ng-repeat-end-watch="ctlr.resize()" ng-model="tile" ph-tile><span>{{tile.number}}</span></div>
</div>

I want the above event in the controller to trigger a series of dom manipulations to 1 or more item DOM elements

The dilemma i am facing is that I am not sure how/ where to build the logic to listen to the said event and proceed with the logic for dom manipulation....

Should it be

1) In a directive controller

return {
            restrict: 'A',
            scope: {
              tile: '=ngModel'
            }, controller: function($scope){ $scope.$on('move', function(){ /* manipulate dom element */}); }

2) Or in the link

return {
                restrict: 'A',
                scope: {
                  tile: '=ngModel'
                }, link: function(scope, element, attr){ scope.$on('move', function(){ /* manipulate dom element */}); }

In addition I need to access the isolated scope's "tile" object and the directive's "element" in order to proceed with the dom manipulation.

Kendall
  • 5,065
  • 10
  • 45
  • 70

1 Answers1

1

It looks like you missed finishing submitting your question, but, in a nutshell, the manipulation of DOM elements should be in link.

Based on what you are starting to write at the bottom ('In addition I need to access the scope's "tile" object and "element" in order to proceed with the'), having the full directive and html, preferably in a demo, would help myself or somebody troubleshoot. I will update this if more information is provided.

Mark Rajcok has done an excellent job explaining the differences between links and controllers here: Difference between the 'controller', 'link' and 'compile' functions when defining a directive

Community
  • 1
  • 1
Brian
  • 4,921
  • 3
  • 20
  • 29
  • Thanks for the heads-up on the mistake. I will try the scenario – Kendall May 27 '16 at 22:38
  • If I use a "link" function....should I then be using `$rootScope` in the link function to listen to events generated from the main controller's $scope( not the directive controller)? – Kendall May 27 '16 at 22:41
  • I would have to know more about the code to answer, but suggest reading this, the author does a good job explaining events: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/. – Brian May 27 '16 at 22:49
  • updated the question to reflect the code. had to strip it down a bit – Kendall May 27 '16 at 23:07
  • 1
    Ok so I *think* (without testing with code) that you should be able to change $scope.$emit to $scope.$broadcast, and listen for that. $emit will send upwards, so with that you would definitely have to listen on $rootScope. This is always a bit trial-by-error for me. – Brian May 27 '16 at 23:14