在单个元素上使用new/isolated作用域的两个属性指令

Two attribute directives with new/isolated scope on single element

本文关键字:指令 属性 两个 作用域 isolated 元素 单个 new      更新时间:2023-09-26

我想使用AngularJS指令在整个应用程序中禁用表单的特定部分,基于用户是否具有特定的角色(作为属性值给定;每个元素可能不同)。该指令的代码是这样的:

/** @ngInject */
function PermissionDirective() {
    var directive = {
        restrict: 'A',
        scope: true,
        bindToController: true,
        controller: controller,
        controllerAs: 'permission',
        link: link
    };
    function link(scope, element, attrs) {
        scope.soPermission = attrs.soPermission;
    }
    return directive;
}
/** @ngInject */
function controller($scope, $attrs, ...) {
    var permission = this;
    permission.granted = false;
    $scope.soPermission = $attrs.soPermission;
    init();
    function init() {
        var requiredPermission = $scope.soPermission;
        permission.granted = // determine if user can use element
    }
}

注意,它需要自己的作用域才能工作。在HTML中的用法是:

<button type="button" ng-disabled="... || !permission.granted" so-permission="WRITE">

只要so-permission是元素中唯一具有新作用域的指令就可以。然而,有些元素也使用确认模态,这似乎也需要一个新的/孤立的作用域。这导致了多个指令…角错误。

我的问题是:你如何解决这个问题?我如何重新设计so-permission指令,以摆脱内部范围,仍然保持它的工作(因为我不能触摸confirm的东西,因为它是一个库)?

您打算给予表单元素的不同权限是什么?也许退一步,从更简单的HTML角度来看待它是可能的?

不创建一个指令,你可以简单地使用ng- attri -readonly和一个函数来分配readonly属性,以确定它是否应该存在。该函数可以存在于表单的控制器中。

<input type="text" ng-attr-readonly="getPermissions()" />

功能:

this.getPermissions = function() {
  if (this.granted === 'READ') return undefined;
  return 'readonly';
}

这个方法适合你的情况吗?

UPDATE:把这个函数变成Factory并重新使用。

angular.module("myApp").factory("PermissionsFactory",PermissionsFactory);
function PermissionsFactory() {
  factory = {
    getPermissions: getPermissions
  }
  return factory;
  function getPermissions(ctrl) {
    if (ctrl.granted === 'READ') return undefined;
    return 'readonly';
  } 
}
然后,在你的控制器中(假设你已经注入了它):
this.getPermissions = PermissionsFactory.getPermissions

最后,在HTML中,确保将控制器传递给函数,因为该函数不再是控制器的一部分,并且需要控制器的作用域来检查权限:

<input type="text" ng-attr-readonly="getPermissions(permission)" />

在angular js中,我们在一个元素上最多只能有一个独立的指令。我建议你试着装饰一下你的指令。查看这篇文章了解更多细节装修指令

你应该使用$parse服务,与scope进行通信:/

** @ngInject */
        function PermissionDirective() {
        var directive = {
        restrict: 'A',
        link: link
    };
function link(scope, element, attrs) {
    var getter = $parse(attrs.soPermission);
    var setter = getter.setter;
    setter(scope, val); // set value to scope
    var value = getter(scope); //get value from scope
}
return directive;
}

也可以使用作用域。