2013-03-14 7 views
1

PlunkerAngularJS - директива сфера не устанавливая нг-класса на элементе

У меня есть таблица данных:

<table class="table table-hover" ng-class="dndElemClass" drag-and-drop> 
    ... 
</table> 

Моя цель состоит в том, чтобы дать таблице отбрасываемой тени, назначив $scope.dndElemClass = 'on-drag-enter' на Элемент ondragenter слушатель события:

.on-drag-enter { 
    -webkit-box-shadow: -3px 3px 5px 3px #ccc; 
    ... 
} 

директива onDragEnter выглядит следующим образом:

directive('dragAndDrop', function() { 
    return { 
     restrict: 'A', 
     controller: function($scope) { 
      $scope.dndElemClass = ''; 
     }, 
     link: function($scope, elem, attr) { 
      $scope.$watch('currentFolder.canUpload', function(newValue, oldValue) { 
       if (newValue && Modernizr.draganddrop && window.File) { 
        elem[0].ondragenter = function(evt) { 
         evt.stopPropagation(); 
         evt.preventDefault(); 
         $scope.$apply(function() { 
          $scope.dndElemClass = 'on-drag-enter'; 
         }); 
        }; 
        elem[0].ondragleave = function(evt) { 
         evt.stopPropagation(); 
         evt.preventDefault(); 
         $scope.$apply(function() { 
          $scope.dndElemClass = ''; 
         }); 
        }; 
        elem[0].ondrop = function(evt) { 
         ... 
        }; 
       } 
      }); 
     } 
    } 
}) 

Несмотря присваивая значение $scope.dndElemClass в слушателей событий ondragenter и ondragleave, то <table> не по всей видимости, признавая значение и присвоения класса как не появляется DropShadow.

До сих пор я тестировал, что он распознает значение, если я задал класс в свойстве контроллера директивы, где я присвоил пустое значение в приведенном выше коде, поэтому я знаю, что он примет его из директивы , Если класс установлен в контроллере в качестве теста, если я запускаю прослушиватель ondragenter, он удаляет класс. Я также подтвердил, что $scope.$apply() правильно присваивает значение scope.dndElemClass с протоколированием, но по какой-либо причине, когда он установлен в $scope.$apply() прослушивателей событий, атрибут ng-class таблицы не распознает назначение переменной и считает, что он пуст.


UPDATE: Согласно комментарию Джоша, я вымыл код так, что я не должен $apply переменных назначений в приемнике событий обратного вызове.

directive('dragAndDrop', function() { 
    return { 
     restrict: 'A', 
     controller: function($scope) { 
      $scope.dndElemClass = ''; 
     }, 
     link: function($scope, elem, attr) { 
      $scope.$watch('currentFolder.canUpload', function(newValue, oldValue) { 
       if (newValue && Modernizr.draganddrop && window.File) { 
        elem.bind('dragenter', function(evt) { 
         evt.stopPropagation(); 
         evt.preventDefault(); 
         $scope.dndElemClass = 'on-drag-enter'; 
        }); 
        elem.bind('dragleave', function(evt) { 
         evt.stopPropagation(); 
         evt.preventDefault(); 
         $scope.dndElemClass = ''; 
        }); 
        elem.bind('drop', function(evt) { 
         //... 
        }); 
       } 
      }); 
     } 
    } 
}) 

По-прежнему не повезло. Я могу проверить, что он выполняет обратные вызовы с протоколированием, но не удастся получить назначение переменной для атрибута ng-class таблицы.


UPDATE 2: я еще больше запутался после прочтения AngularJS's documentation on ngClass. Для меня я подумал, что это так же просто, как установить имя (s в массиве) классов, которые вы хотите для переменной в текущем контроллере (или в моем случае, директиве) $scope, затем укажите имя этой переменной, как если бы вы где-нибудь еще в атрибуте элемента ng-class="". Но, как я читаю, кажется, что это намного сложнее, поскольку люди используют expressions или toggling the class name(s).

Используя идею переключени, я раздвоенный my plunker воссоздать ситуацию настройки $scope.dndElemClass в логическое значение, основанное на триггеры ли пользователь dragenter или dragleave. Я также включил $scope.$apply() для хорошей оценки, так как обнаруживаю, что я не понимаю преимущества angular.bind() за .addEventListener или .ondragenter = function() {};. Несмотря ни на что, ничто из этого не привело к тому, что класс таблицы был настроен так, как я ожидал.

+0

Почему вы оставляете AngularJS World для запуска события, чтобы попытаться повторно ввести его, чтобы установить переменную области? Почему бы просто не использовать 'elem.bind ('dragenter', function() {...})'? Попробуйте упростить свой код и посмотреть, разрешает ли это проблема. –

+0

Не был знаком с Angle's .bind(). После очистки и избавления от '$ apply()' все равно не повезло. – Scott

+0

Это, вероятно, проблема с областью. Можете ли вы опубликовать простой Plunker для демонстрации? –

ответ

1

Я не уверен, что вам все еще нужен ответ, но я мог бы исправить ваш плунж.

Внутри контроллера CurrentFolder, добавьте

$scope.dndElemClass = ''; 

Затем обернуть $scope.dndElemClass внутри $apply.

$scope.$apply(function() { $scope.dndElemClass = 'on-drag-enter'; }); 

Проверьте complete plunk для более четкого изображения.

enter image description here

+0

В этом ответе была исправлена ​​аналогичная проблема, с которой я столкнулся - настройка scope.myVar контроллера изнутри директивы. Класс ng ожидал изменения, но ничего не изменилось при изменении myVar. Обмануть его в том, что $ apply был трюк! Спасибо за этот ответ! – JT703

0

попытка установить класс в сферу затем использовать class={{classVariable}} !!! Это работает для меня.

Смежные вопросы