Функция ссылки директивы Angular вызывается с пустым параметром элемента

У меня есть сценарий, в котором функция link директивы вызывается с пустым параметром element, что приводит к ошибкам.

Пример кода лучше всего описывает сценарий:

индекс.html:

<html ng-app="app">
<body>
    <div outer></div>
</body>
</html>

Скрипты:

var app = angular.module('app', []);

app.directive('outer', function() {
    return {
        replace: true,
        controller: function($scope) {
            $scope.show = true;
        },
        templateUrl: 'partial.html'
    };
});

app.directive('inner', function($window) {
    return {
        link: function(scope, element, attrs) {
            console.log('element: ' + element);
            var top = element[0].offsetTop;
        }
    };
});

partial.html (на который ссылается templateUrl в outer выше):

<div ng-switch on="show">
    <div ng-switch-when="true">
       <div inner>showing it</div>
    </div>
</div>

При загрузке index.html в Chrome консоль сообщает об ошибке: «Ошибка типа: невозможно прочитать свойство 'offsetTop' of undefined» — потому что element — это пустой массив!

Некоторые примечания:

  • replace должно быть установлено значение true в директиве outer.
  • templateUrl должен использоваться директивой outer для загрузки своего частичного файла.

Я не уверен, пропустил ли я какое-то требование к конфигурации или это проблема Angular. Это верный сценарий? Если это так, то проблема в ng-switch или в Angular есть более глубокая проблема?


person Paul Pepper    schedule 03.04.2013    source источник
comment
ng-switch, кажется, дважды вызывает директиву. В первый раз элемент не существует в директивной функции, во второй раз он существует (вероятно, фаза компиляции ng-switch). Возможно, это не лучшее решение, но if(element.length) работает plnkr.co/edit/sxfHOarFr5OcFMIt3dRj   -  person charlietfl    schedule 03.04.2013
comment
Насколько я понимаю, фаза компиляции не вызывает функцию link директивы - это правильно? Ре. охранник, см. мой ответ @arun-p-johny ниже.   -  person Paul Pepper    schedule 03.04.2013
comment
не уверен на 100%, почему ... но посмотрите на демонстрацию входа в консоль. При запуске стороннего кода, такого как jQuery... он будет молча терпеть неудачу, если element.somePlugin() пуст.   -  person charlietfl    schedule 03.04.2013
comment
То, что Angular дважды вызывает функцию outer''s link`, кажется странным — 1-й без действительного параметра element, 2-й с допустимым параметром element. Отсутствие ng-switch дает ожидаемый результат одного вызова link (см. plnkr.co/fV2yq1wy8jignNmfgp8Y).   -  person Paul Pepper    schedule 04.04.2013


Ответы (1)


Пытаться

app.directive('inner', function($window) {
    return {
        link: function(scope, element, attrs) {
            console.log('element: ',  element);
            if(!element.length){
              console.log('Returning since there is no element');
              return;
            }
           var top = element[0].offsetTop;
           console.log('top', top)
        }
    };
});
person Arun P Johny    schedule 03.04.2013
comment
Да, элемент проверки будет работать, за исключением того, что директива inner может быть сторонним компонентом. На самом деле я столкнулся с этой проблемой, используя компонент angular-ui. Я пытаюсь понять, что делает angular (возможно, по ошибке), а не способы эффективной защиты от этой проблемы. - person Paul Pepper; 03.04.2013