AngularJS - 指令范围不在元素上设置ng-class

时间:2013-03-14 20:47:18

标签: angularjs angularjs-directive angularjs-scope

Plunker

我有一张数据表:

<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.dndElemClassondragenter事件侦听器中分配了ondragleave的值,但<table>似乎没有识别该值并将该类指定为no drophadow出现。

到目前为止,我已经测试过它确实识别了值,如果我在指令的controller属性中设置了类,我在上面的代码中将它指定为空白,所以我知道它会从指令接受它。将类在控制器中设置为测试,如果我触发ondragenter侦听器,它将删除该类。我还确认$scope.$apply()正在使用日志记录正确分配scope.dndElemClass的值,但无论出于何种原因,当在事件监听器的$scope.$apply()中设置时,表ng-class属性将无法识别变量赋值并认为它是空的。


更新 根据Josh的评论,我清理了代码,以便在事件监听器回调中没有$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属性识别。


更新2:阅读AngularJS's documentation on ngClass后,我更加困惑。对我来说,我认为这就像在当前控制器(或者在我的情况下,指令中)$scope中设置要变量的类的名称(数组中的s)一样简单,然后指定变量的就像你在元素ng-class=""属性中的任何其他位置一样。但正如我正在阅读的那样,当人们使用expressionstoggling the class name(s)时似乎更复杂。

使用切换的想法,我分叉my plunker以根据用户是触发$scope.dndElemClass还是dragenter将情境设置dragleave重新设置为布尔值。我还包括$scope.$apply()以获得良好的衡量标准,因为我发现我不理解angular.bind()优于.addEventListener.ondragenter = function() {};的优势。无论如何,这些都没有导致表的类被设置为我期望的那样。

2 个答案:

答案 0 :(得分:1)

我不确定你是否还需要一个答案,但我可能已经解决了你的问题。

CurrentFolder控制器内,添加

$scope.dndElemClass  = '';

然后将$scope.dndElemClass包裹在$apply内。

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

检查complete plunk以获得更清晰的图片。

enter image description here

答案 1 :(得分:0)

尝试在范围中设置课程,然后使用class={{classVariable}}! 这对我有用。