56

我正在使用“可拖动”指令来支持图像拖动。但是,根据用户的角色,我需要为某些用户组禁用图像拖动。我使用了以下代码。

<!--draggable attribute is used as handle to make it draggable using jquery event-->           
<li  ng-repeat="template in templates" draggable id="{{template._id}}" type="template" class="template-box">            
<!-- Images and other fields are child of "li" tag which can be dragged.-->                    
</li> 

该方法dragSupported在模板范围内并返回trueor false。我不想通过使用返回的每个值来创建两个大的重复<li>元素。换句话说,我不是在寻找以下方法来解决这个问题。ng-ifdragSupported()

<!--draggable attribute is used as handle to make it draggable using jquery event-->           
<li ng-if="dragSupported() ==true"  ng-repeat="template in templates" draggable id="{{template._id}}" type="template" class="template-box">            
<!-- Images and other fields are child of "li" tag which can be dragged.-->                    
</li>
<!--remove "draggable" directive as user doesn't have permission to drag file -->
<li ng-if="dragSupported() !=true"  ng-repeat="template in templates"  id="{{template._id}}" type="template" class="template-box">            
<!-- Images and other fields are child of "li" tag which can be dragged.-->                    
</li>

有没有其他方法可以避免代码重复?

4

4 回答 4

58

ng-attr-<attrName>

ng-attr-<attrName>Angular 作为动态标题指令包含了对有条件地声明 HTML 属性的支持。

官方文档ng-attr

例子

在您的情况下,代码可能如下所示:

<li
    id="{{template._id}}"
    class="template-box"
    type="template"
    ng-repeat="template in templates"
    ng-attr-draggable="dragSupported() === true"
></li>

演示

JSFiddle

这包含以下值的用法示例:truefalseundefinednull10""。请注意通常错误的值如何产生意想不到的结果。

于 2014-10-01T18:32:03.157 回答
6

感谢杰森的建议。我在这里采取了一些不同的方法。由于我不想更改“范围”变量,因此我使用“attrs”来检查是否允许拖动。以下是目前看来不错的方法 I 工具。

指令代码:

app.directive('draggable', function () {
    return {
        // A = attribute, E = Element, C = Class and M = HTML Comment
        restrict: 'A',
        replace:true,
        link: function (scope, element, attrs) {

            if(attrs.allowdrag =="true")
            {
                element.draggable({
                cursor: 'move',
                helper: 'clone',
                class:'drag-file'
                });
            }

        }
    }
});

HTML 代码:

<ul> 
         <!--draggable attribute is used as handle to make it draggable using jquery event-->           
        <li  ng-repeat="template in templates" draggable allowdrag="{{userHasPrivilege()}}" >            
                <!--Ohter code part of li tag-->                   

        </li> 

</ul>

控制器正在执行 userHasPrivilege()。

不确定这是否正确。寻找想法。

于 2013-09-15T20:23:48.373 回答
3

无法直接从元素中添加或删除属性。但是,您可以创建一个指令,在满足条件时简单地将属性添加到元素。我已经把一些东西放在一起来说明这种方法。

演示:http: //jsfiddle.net/VQfcP/31/

指示

myApp.directive('myDirective', function () {
  return {
    restrict: 'A',
    scope: {
        canDrag: '&'
    },
    link: function (scope, el, attrs, controller) {
        /*
$parent.$index is ugly, and it's due to the fact that the ng-repeat is being evaluated 
first, and then the directive is being applied to the result of the current iteration      
of the repeater.  You may be able to clean this by transcluding the repeat into the 
directive, but that may be an inappropriate separation of concerns. 
You will need to figure out the best way to handle this, if you want to use this approach.  
  */
        if (scope.canDrag&& scope.canDrag({idx: scope.$parent.$index})) {
            angular.element(el).attr("draggable", "draggable");
        }
    }
  };
});

HTML

<ul>
    <!-- same deal with $parent -->
    <li ng-repeat="x in [1, 2, 3, 4, 5]" my-directive="true" can-drag="checkPermissions(idx)">{{$parent.x}}</li>
</ul>

控制器

function Ctl($scope) {
   $scope.checkPermissions = function(idx) {
     // do whatever you need to check permissions
     // return true to add the attribute
   }
}
于 2013-09-14T05:40:10.133 回答
0

我使用了不同的方法,因为前面的示例对我不起作用。也许它与使用自定义指令有关?也许有人可以澄清这一点。

在我的特定示例中,我使用的是 ui-grid,但并非所有 ui-grid 都应该使用分页。我传入一个“分页”属性,然后根据真/假 $compile 指令。看起来很野蛮,但希望它可以将人们推向积极的方向。

HTML

<sync-grid service="demand" paginated="true"></sync-grid>

指示

angular
    .module('app.directives')
    .directive('syncGrid', ['$compile', SyncGrid]);

function SyncGrid($compile){
    var nonPaginatedTemplate = '' +
        '<div>' +
        '   <div ui-grid="gridOptions" class="grid"></div>' +
        '</div>';

    var paginatedTemplate = '' +
        '<div>' +
        '   <div ui-grid="gridOptions" class="grid" ui-grid-pagination></div>' +
        '</div>';


    return {
        link: link,
        restrict: 'E',
        replace: true
    };

    function link(scope, element, attrs) {

        var isPaginated = attrs['paginated'];

        var template = isPaginated ? paginatedTemplate : nonPaginatedTemplate;
        var linkFn = $compile(template);
        var content = linkFn(scope);
        element.append(content);

        // Continue with ui-grid initialization code
        // ...

    }
}
于 2016-06-21T14:12:31.937 回答