Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs: Directive NEVER called

I have a directive that spontaneously stopped working. For some reason, it is never called with no error prints out in the console. This is odd because other directives (which seem virtually identical) are working (see the very end of the post for a working directive).

This is the directive:

angular.module('popup').directive('popup', ['Locator', 'PopupService', // This line of code is reached
    function(Locator, PopupService) {
        return {
            restrict: 'A',
            scope: {
                "show": '=',
                "anchor": '=',
                'direction': '='
            },
            link: function($scope, element, attr) { // This never called
                $scope.$watch('show', function(newValue, oldValue) {
                    if (newValue) { // This is never called
                        var pos = Locator.getCenterPosition($($scope.anchor));
                        PopupService.togglePopup($(element), {
                            x: pos.x,
                            y: pos.y,
                            origin: $scope.direction,
                            remove_callback: function() {
                                $scope.show = false;
                                console.log("SHOW: " + $scope.show);
                            }
                        });
                    } else {
                        autoHide();
                    }
                }, true);
            }
        };
    }
]);

This is the Jade code including the directive (Jade is an html templating language.):

block total-content
  .div {{ edit }}
  .main-body(ng-controller="editEditorController" ng-init="popups = {};format.colorMode='W'; draftID='#{draftID}'; draftEditorID='#{draftEditorID}'; draftOwnerID='#{draftOwnerID}' ")
    div {{ commentEditor }}
    ul#left-tool-list.side-tool-list.tool-list()
      li#comments-tool-box
        span.tool-box-title Comments
        span.tool-box-control-area
          #tool-box-controls
            span#comment-button.tool-box-button(ng-click="newComment()") Add Comment
            span#view-comments-button.tool-box-button(ng-init="popups.showCommentPopup = false" ng-click="popups.showCommentPopup = true; $event.stopPropogation();" stop-event='click') View Comments
          div#comment-list-container(popup show="popups.showCommentPopup" anchor="'#view-comments-button'" direction="'top'") // The directive in question
            comment-displayer#comment-list(edit="edit")

This is the declaration for the app:

var editEditorApp = angular.module('editEditorApp', ['general', 'API', 'popup']);

And this is the order of the includes:

  /* App */   script(src='/js/angular/editEditor/editEditorApp.js')
  /* JQuery */   script(src='/js/pxem.JQuery.js')
  /* Plain JS */   script(src='/styles/js/window-height.js')
  /* Tinymce */   script(src='/js/ice_tinymce/tinymce/jscripts/tiny_mce/tiny_mce.js')
  /* JQuery dep. */   script(src='/js/jquery.browser.min.js')
  /* Angular Module - factory */   script(src='/js/angular/api/api.js')
  /* Angular Module - directives */   script(src='/js/angular/directives/general.js')
  /* Angular Module - popup (services) */   script(src='/js/angular/general/popupService.js')
  /* Angular Module - popup (directive) */   script(src='/js/angular/directives/popup.js')
  /* Angular Module */   script(src='/js/angular/filter/cut.js')
  /* Angular Module - factory */   script(src='/js/angular/editEditor/commentLikeCreator.js')
  /* Angular Module - factory */   script(src='/js/angular/editEditor/autoSave.js')
  /* Angular Module - directives */   script(src='/js/angular/editEditor/commentBox.js')
  /* Angular Module - directives */   script(src='/js/angular/editEditor/editor.js')

This directive is working, but I don't know why it is:

editEditorApp.directive('commentBox',
    function(PopupService) {
        return {
            restrict: 'E',
            templateUrl: "/partials/edit-comment-box",
            replace: true,
            scope: {
                "comment": '=',
                "onDelete": '=',
                "onHide": '=',
                "location": '=',
                "show": '='
            },
            link: function($scope, element, attr) {
                console.log("LINK POPUP");
                $scope.$watch('show', function(newValue, oldValue) {
                    console.log("NEW VALUE: " + newValue);
                    if (newValue) {
                        console.log("SHOW!");
                        $scope.popup = PopupService.popPopup($(element), {
                            x: location.x,
                            y: location.y,
                            origin: 'bottom',
                            hideOthers: true,
                            remove_callback: function() {
                                $scope.show = false;
                                console.log("SHOW: " + $scope.show);
                            }
                        });
                    } else {
                        if ($scope.popup) {
                            $scope.popup.removePopup();
                        }
                    }
                });
            },
            controller: function($scope) {
                console.log("CONTROLLER");
                $scope.delete = function() {
                    $scope.popup.removePopup();
                    if ($scope.onDelete) {
                        $scope.onDelete();
                    }
                };
                $scope.hide = function() {
                    $scope.popup.removePopup();
                    if ($scope.onHide) {
                        $scope.onHide();
                    }
                };
            }
        };
    }
);

Note: This problem was previously posted under a different question, but I realize now that it wasn't the "watch" part of the directive that was broken, but that the directive was never called. I deleted the aforementioned question and posted this one.

like image 713
sinθ Avatar asked Jun 07 '14 18:06

sinθ


2 Answers

Notice the difference you use your module in the first one and your declaration and usage of module in the second one.

In the first one where it is not working, you are not putting any dependencies. Even you do not have any, just put an empty array.

angular.module('popup',[]).directive('popup', ['Locator', 'PopupService', // This line of code is reached
    function(Locator, PopupService) {
        return {
            restrict: 'A',
            scope: {
                "show": '=',
                "anchor": '=',
                'direction': '='
            },
            link: function($scope, element, attr) { // This never called
                $scope.$watch('show', function(newValue, oldValue) {
                    if (newValue) { // This is never called
                        var pos = Locator.getCenterPosition($($scope.anchor));
                        PopupService.togglePopup($(element), {
                            x: pos.x,
                            y: pos.y,
                            origin: $scope.direction,
                            remove_callback: function() {
                                $scope.show = false;
                                console.log("SHOW: " + $scope.show);
                            }
                        });
                    } else {
                        autoHide();
                    }
                }, true);
            }
        };
    }
]);
like image 197
geckob Avatar answered Nov 09 '22 09:11

geckob


This is not yet a complete answer and will be updated if more information is given. But, a few things that help me in such cases:

  • According your list of includes you don't include angular yet. Add angular as include if it's missing.
  • There is no code that changes the watched show variable to anything that evaluates to true. Make your code change the show variable to get if(newValue) executed.

If the previous points do solve the problem, here some suggestions on how to narrow down the problem:

  • The working directive is included in the same module editEditorApp, whereas the non-working directive is included in another module, that is dependency injected. Try declaring the directive on editEditorApp.
  • The directive is called like the module, AFAIK this should be no problem, but it could not hurt to try to rename it.

This answer is a work in progress for a better answer you need to narrow down the problem to a reproducible example, i.e. all code is available. Otherwise everything remains guesswork! So far this answer is meant as:

Help us find a solution by researching the problem, then contribute the results of your research and anything additional you’ve tried as a partial answer.

as the guidelines suggest.

like image 45
jan.vogt Avatar answered Nov 09 '22 10:11

jan.vogt