Note that there are some explanatory texts on larger screens.

plurals
  1. POAngularJS - directive scope not setting ng-class on element
    text
    copied!<p><a href="http://plnkr.co/edit/QJqICyTrdvAZvSjQ5Gi9" rel="nofollow">Plunker</a></p> <p>I have a table of data:</p> <pre><code>&lt;table class="table table-hover" ng-class="dndElemClass" drag-and-drop&gt; ... &lt;/table&gt; </code></pre> <p>My goal is to give the table a drop shadow by assigning <code>$scope.dndElemClass = 'on-drag-enter'</code> on the element's <code>ondragenter</code> event listener:</p> <pre><code>.on-drag-enter { -webkit-box-shadow: -3px 3px 5px 3px #ccc; ... } </code></pre> <p>The <code>onDragEnter</code> directive is as follows:</p> <pre><code>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 &amp;&amp; Modernizr.draganddrop &amp;&amp; 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) { ... }; } }); } } }) </code></pre> <p>Despite assigning the value of <code>$scope.dndElemClass</code> in the <code>ondragenter</code> and <code>ondragleave</code> event listeners, the <code>&lt;table&gt;</code> doesn't appear to be recognizing the value and assigning the class as no dropshadow appears.</p> <p>Thus far I've tested that it does recognize the value if I set the class in the controller property of the directive where I have it assigned to blank in the above code, so I know it will accept it from the directive. With the class set in the controller as a test, if I trigger the <code>ondragenter</code> listener, it removes the class. I've also confirmed that the <code>$scope.$apply()</code> is properly assigning the value of <code>scope.dndElemClass</code> with logging, but for whatever reason, when set in the event listeners's <code>$scope.$apply()</code>, the table's <code>ng-class</code> attribute won't recognize the variable assignment and thinks it's empty.</p> <hr> <p><strong>UPDATE:</strong> As per Josh's comment, I cleaned up the code so that I didn't have to <code>$apply</code> the variable assignment in the event listener callbacks.</p> <pre><code>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 &amp;&amp; Modernizr.draganddrop &amp;&amp; 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) { //... }); } }); } } }) </code></pre> <p>Still no luck. I can verify it is executing the callbacks with logging, but no luck on getting the variable assignment to be recognized by the table's <code>ng-class</code> attribute.</p> <hr> <p><strong>UPDATE 2:</strong> I am even more confused after reading through <a href="http://docs.angularjs.org/api/ng.directive%3angClass" rel="nofollow">AngularJS's documentation on ngClass</a>. To me, I thought it was as simple as setting the name(s in an array) of the classes you want to a variable in the current controller's (or in my case, the directive's) <code>$scope</code>, then specify that variable's name like you would anywhere else in the element's <code>ng-class=""</code> attribute. But as I'm reading, it seems like it's more much complicated as people are using <a href="http://docs.angularjs.org/api/ng.directive%3angClass#comment-758028928" rel="nofollow">expressions</a> or <a href="http://jsfiddle.net/mrajcok/nFcLh/" rel="nofollow">toggling the class name(s)</a>.</p> <p>Using the idea of toggling, I forked <a href="http://plnkr.co/edit/U6EtAEOBsWLIduhoMUma" rel="nofollow">my plunker</a> to recreate the situation setting <code>$scope.dndElemClass</code> to a boolean value based on whether the user triggers <code>dragenter</code> or <code>dragleave</code>. I also included <code>$scope.$apply()</code> for good measure, as I am finding that I don't understand the advantage of <code>angular.bind()</code> over <code>.addEventListener</code> or <code>.ondragenter = function() {};</code>. Regardless, none of this has caused the table's class to get set as I would expect it to.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload