personalizadas directivas crear javascript angularjs angularjs-directive

javascript - crear - directivas personalizadas angular 5



AngularJS-Usa la directiva de atributos condicionalmente (4)

ng-attr-<attrName>

El soporte para declarar condicionalmente un atributo HTML se incluye con Angular como la directiva ng-attr-<attrName> titulada dinámicamente.

Documentos oficiales para ng-attr

Ejemplo

En su caso, el código podría verse así:

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

Manifestación

JSFiddle

Esto contiene ejemplos de uso para los siguientes valores: true , false , undefined , null , 1 , 0 y "" . Tenga en cuenta cómo los valores típicos falsey pueden arrojar resultados inesperados.

Estoy usando una directiva "arrastrable" para soportar el arrastre de imágenes. Sin embargo, según el rol del usuario, necesito desactivar el arrastre de imágenes para ciertos grupos de usuarios. He usado el siguiente código.

<!--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>

El método dragSupported está en el alcance de la plantilla y devuelve true o false . No quiero crear dos grandes elementos <li> duplicados utilizando ng-if para cada valor devuelto por dragSupported() . En otras palabras, no estoy buscando el siguiente enfoque para resolver esto.

<!--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>

¿Hay algún otro enfoque para evitar la duplicidad del código?


Gracias Jason por tu sugerencia. Me tomé un enfoque diferente aquí. Como no quiero cambiar la variable "scope", utilicé "attrs" para verificar si el arrastre está permitido o no. Lo siguiente es una herramienta de aproximación I que parece buena hasta ahora.

Código directivo:

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'' }); } } } });

Código 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>

El controlador tiene una implementación de userHasPrivilege ().

No estoy seguro de si esta es la forma correcta o no. Buscando pensamientos.


No hay forma de agregar o quitar directamente un atributo de un elemento. Sin embargo, podría crear una directiva que simplemente agregue el atributo al elemento cuando se cumpla la condición. He creado algo que ilustra el enfoque.

Demostración: http://jsfiddle.net/VQfcP/31/

Directiva

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>

Controlador

function Ctl($scope) { $scope.checkPermissions = function(idx) { // do whatever you need to check permissions // return true to add the attribute } }


Usé un enfoque diferente ya que los ejemplos anteriores no me funcionaron. ¿Tal vez tiene que ver con el uso de directivas personalizadas? Quizás alguien pueda aclarar eso.

En mi ejemplo particular, estoy usando ui-grid, pero no todas las ui-grids deberían usar paginación. Paso en un atributo "paginado" y luego compilo $ la directiva basada en verdadero / falso. Parece bastante brutal pero con suerte puede empujar a las personas en una dirección positiva.

HTML

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

Directiva

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 // ... } }