admin管理员组

文章数量:1352819

The function that I'm providing to define my directive is never called. It used to work fine but suddenly stopped working and I have no idea why.

Here's my directive:

portalApp.directive('contactPanel', function () {
    console.log("NEVER SHOWN!");
    return {
        restrict: 'AE',
        replace: 'true',
        templateUrl: 'partials/account/contactPanel.html',
        scope: {
            contact: '=contact',
            primaryRoleName: '@',
            roleName: '@',
            primary: '=primary',
            locations: '=locations'
        },
        controller: function (userService, $rootScope, $scope) {
            ...snip...
        }
    };
});

and here an example of its use:

<contact-panel contact="user.account.contacts.billing" role-name="billing"
               locations="locations"></contact-panel>

Note that I'm using the correct casing, i.e. camel-case in JS and hyphenation in HTML.

The key clue is that the message that's logged in the second line (i.e. 'NEVER SHOWN!') never shows up in the console. If I log a message immediately before the directive declaration then that shows up, so this code is being executed by the interpreter, but the framework is just never using my declaration.

I'd love to have an answer obviously, but I'd also love to hear of some approaches to debug this kind of problem.

The function that I'm providing to define my directive is never called. It used to work fine but suddenly stopped working and I have no idea why.

Here's my directive:

portalApp.directive('contactPanel', function () {
    console.log("NEVER SHOWN!");
    return {
        restrict: 'AE',
        replace: 'true',
        templateUrl: 'partials/account/contactPanel.html',
        scope: {
            contact: '=contact',
            primaryRoleName: '@',
            roleName: '@',
            primary: '=primary',
            locations: '=locations'
        },
        controller: function (userService, $rootScope, $scope) {
            ...snip...
        }
    };
});

and here an example of its use:

<contact-panel contact="user.account.contacts.billing" role-name="billing"
               locations="locations"></contact-panel>

Note that I'm using the correct casing, i.e. camel-case in JS and hyphenation in HTML.

The key clue is that the message that's logged in the second line (i.e. 'NEVER SHOWN!') never shows up in the console. If I log a message immediately before the directive declaration then that shows up, so this code is being executed by the interpreter, but the framework is just never using my declaration.

I'd love to have an answer obviously, but I'd also love to hear of some approaches to debug this kind of problem.

Share Improve this question edited Sep 29, 2015 at 12:26 John Slegers 47.1k23 gold badges204 silver badges173 bronze badges asked Sep 15, 2015 at 2:05 HansAHansA 1,3752 gold badges11 silver badges20 bronze badges 7
  • any error in console ? – Anik Islam Abhi Commented Sep 15, 2015 at 2:09
  • Are there any errors in the console? Are you testing a page where the contact-panel is present on? – micah Commented Sep 15, 2015 at 2:09
  • use console.log in controller instead of outside – Manikanta Reddy Commented Sep 15, 2015 at 2:11
  • No, there's no error in the console. As far as I can see, there's no point in logging in the controller because we know that the code that defines that controller is never called, but I did it anyway and confirmed that it was not shown in the console. – HansA Commented Sep 15, 2015 at 2:15
  • Seems positive then that the html you have there isn't present on the page, or you've added it in a way foreign to Angular (dom manipulation that isn't piled). – m59 Commented Sep 15, 2015 at 2:16
 |  Show 2 more ments

2 Answers 2

Reset to default 8

I can see only 2 possibilities that would exhibit the behavior you described. Either the HTML with the directive was not piled or the directive is not registered.

The "not piled" case could be because the directive is used outside of the Angular app, for example:

<div ng-app="portalApp">
 ...
</div>
...
<contact-panel></contact-panel>

Or, if you added the HTML dynamically, but did not $pile and link it.

The "not registered" case could be due to re-registration of the app's module. In other words, you might have the following case:

var portalApp = angular.module("portalApp", []);
portalApp.directive("contactPanel", function(){...});

// then elsewhere you use a setter:

angular.module("portalApp", []).controller("FooCtrl", function(){});    
// instead of the getter:
// var app = angular.module("portalApp");

The second call to angular.module("portalApp", []) removes the previous registration of .directive("contactPanel", ....

I figured out the cause of this problem. At some point I must've accidentally moved the directive into a configuration block like this:

portalApp.config(function ($stateProvider, $urlRouterProvider) {
    portalApp.directive('contactPanel', function () {
        console.log("NEVER SHOWN!");
        return {
            ...snip...
        };
    });
});

Once I moved it back out of the configuration block and into the global scope the directive immediately rendered as it should.

The reason why this doesn't work is that angular runs the configuration code after it's run the directives, like this:

runInvokeQueue(moduleFn._invokeQueue);    // runs directives
runInvokeQueue(moduleFn._configBlocks);   // runs config blocks

So things added to the _invokeQueue (which the directive() function does) from within a config block will never be executed.

Thank you to all those who tried to help.

本文标签: javascriptAngularJSdirective function not calledStack Overflow