Почему функция ссылки моей директивы никогда не называется?

У меня есть эта директива:

    hpDsat.directive('ngElementReady', [function() {
        return {
            restrict: "A",
            link: function($scope, $element, $attributes) {
                // put watches here.
                console.log(" WHAT THE @#%*%$??? ");
                $scope.$eval($attributes.ngElementReady);
            }
        };
    }]);

Я никогда не вижу вывод console.log. Я объявляю такой элемент:

<div data-ng-element-ready="console.log(' ------------------------------- COMPILED! ')" data-ng-if="analysis.type" data-ng-show="showBasicHtml" data-ng-include="analysis.type+'Content.html'"></div>

Да, я объявляю директиву, прежде чем объявить контроллер, под которым существует элемент div. Элемент появляется, ngShow и ngInclude работают, и что-либо в загруженном шаблоне тоже отлично работает (больше директив, контроллеров, {{expression}} и т.д.).

Если я выполняю его с помощью функции компиляции, функция компиляции работает, но все же не является функцией ссылки:

    hpDsat.directive('ngElementReady', [function() {
        return {
            restrict: "A",
            compile: function($element, $attributes) {
                console.log("This I do see."); // THIS WORKS!!
                return function($scope) {
                    // put watches here.
                    console.log("But not this. Why???"); // DOESN'T WORK!!
                    $scope.$eval($attributes.ngElementReady);
                };
            }
        };
    }]);

Консоль .log функции компиляции работает нормально, но возвращаемая функция ссылки все равно никогда не выполняется.

Любая идея, почему функция ссылки не может быть запущена?

Ответ 1

Ошибка может быть где-то еще. Я попробовал его в jsfiddle и работает первая версия.

Eval()

В любом случае у вас может быть недоразумение о том, что делает $scope.$eval():

$scope.$eval() оценивает угловой код в области видимости. Функция JavaScript eval() для запуска произвольного js-кода в angularjs составляет $window.eval(). Подробнее об этом здесь: Angular.js: Как работает $eval и почему он отличается от ванильного eval?

Я протестировал директиву, изолированную от контроллера:

<div data-ng-element-ready="console.log('COMPILED!')"></div>

и директива:

app.directive('ngElementReady', ['$window', function($window) {
return {
    restrict: "A",
    link: function($scope, $element, $attributes) {
        console.log("Reached the link fn", $attributes);
        $window.eval($attributes.ngElementReady);
    }
};
}]);

Я получаю значение "достигло ссылки fn" и $attributes верно:

Reached the link fn Object { $$element={...}, $attr={...},  
ngElementReady="console.log('COMPILED!')", more...}

И $window.eval() возвращает COMPILED!

и здесь с контроллером.

в любом случае, использование eval() для выполнения кода, написанного в атрибуте, выглядит опасным. Любой может изменить DOM для запуска кода там. По крайней мере, убедитесь, что это не повлияет на других пользователей или сервер.

Воспроизведение проблемы с помощью ng-if

Отредактировано после первого комментария: Я попытался сделать выражение ng-if для выражения false здесь На этот раз сообщение не отображается. Это, вероятно, происходит потому, что для оценки ng-if, yuo должен сначала скомпилировать директиву. в противном случае, это просто код, о котором не знает anuglarjs. Однако, поскольку он удален из DOM, он никогда не достигает функции ссылки.

Порядок выполнения функций AngularJS

В общем случае порядок выполнения выглядит следующим образом (Джош Дэвид Миллер объясняет это:

<div directive1>
  <div directive2>
    <!-- ... -->
  </div>
</div>

Теперь AngularJS создаст директивы, запустив директивные функции в определенном порядке:

directive1: compile
  directive2: compile
directive1: controller
directive1: pre-link
  directive2: controller
  directive2: pre-link
  directive2: post-link
directive1: post-link