14

最近我必须让 Input 元素同时使用 ng-disabled 和自定义指令,它使用隔离范围来评估表达式,就像 ng-disabled 正在做的那样,不知何故,自定义指令可以正常工作,但 ng-disabled 不能,因为它只评估孤立范围内的表达式。

自定义指令非常简单,例如:

angular
  .module('directives', [])
  .directive('conditionalAutofocus', function () {
    return {
        restrict:'A',
        scope:{
            condition:'&conditionalAutofocus'
        },
        link:function (scope, element, attrs) {
            if (scope.condition()) {
                attrs.$set('autofocus','true');
            }
        }
    }
});

而页面看起来像:

<input name="pin"
       ng-model="pin"
       type="password"
       required
       ng-disabled="names == null"
       conditional-autofocus="names != null" />

有人已经有这个问题的解决方案了吗?

提前致谢!雅尼

4

5 回答 5

20

我有同样的问题,最简单的解决方案恕我直言。就是利用隔离作用域继承ngDisabled的属性。

angular.module('directives', [])
.directive('conditionalAutofocus', function () {
    return {
        restrict:'A',
        scope:{
            condition:'&conditionalAutofocus',
            disabled:'=ngDisabled'
        },
        link:function (scope, element, attrs) {
            if (scope.condition()) {
                attrs.$set('autofocus','true');
            }
            if(scope.disabled){
                //is disabled
            }
        }
    }
});

可能只适用于限制:'E'。没有测试过其他人

于 2015-03-20T13:51:46.543 回答
4

我最近遇到了类似的问题。我想禁用孤立范围内的按钮并使用这个漂亮的角度ng-disabled指令。经过一番挖掘,我得出了这样的解决方案:

link: function($scope, element, attrs){

    $scope.$parent.$watch(attrs.ngDisabled, function(newVal){
        element.prop('disabled', newVal);
    });

    //...
}

要评估ng-diabled表达式,而不是$scope仅仅跳转到$scope.$parent,您的所有变量都将可用。不幸的是,需要手动设置 disabled 属性。

于 2013-04-15T08:22:03.220 回答
2

好的,对于我自己的情况,我的解决方案是更改指令的实现,不再使用隔离范围:

angular.module('directives', [])
.directive('conditionalAutofocus', function () {
    return {
        restrict:'A',
        link:function (scope, element, attrs) {
            scope.$watch(attrs.conditionalAutofocus, function(){
                if (scope.$eval(attrs.conditionalAutofocus)) {
                    element.focus();
                }else{
                    element.blur();
                }
            });
        }
    }
});
于 2012-12-26T03:08:32.097 回答
1

您可以在隔离范围定义中设置与父范围的双向绑定。然后在隔离范围属性上添加一个监视。这只是复制了 ngReadonly 指令中的代码。

angular.module('directives', [])
.directive('conditionalAutofocus', function () {
    return {
        restrict:'A',
        scope:{
            condition: '&conditionalAutofocus',
            isReadonly: '=ngReadonly'
        },
        link:function (scope, element, attrs) {
            if (scope.condition()) {
                attrs.$set('autofocus','true');
            }

            scope.$watch('isReadonly', (value) => {
                attrs.$set('readonly', !!value);
            });
        }
    }
});
于 2013-05-14T19:59:38.363 回答
0

您不需要其他答案的任何复杂性。问题是您的指令甚至不知道 wtf ng-Disabled 是。如果您想在模板中使用 ng-Disabled,则必须将其注入您的范围或需求中。例如,这不起作用:

.directive('myDirective', function () {
    return {
        restrict: 'E',
        template: '<input type="text" ng-disabled="fieldDisabled" />',
        scope:{ something: '=' },
        link: function (scope, element, attrs) {
            scope.something = attrs.something;
        },
        controller: function($scope) {
            $scope.fieldDisabled = false;
            $scope.myAction = function() {
                $scope.fieldDisabled = true;
            };
        }
    }
});

但以下起作用:

.directive('myDirective', function () {
    return {
        restrict: 'E',
        template: '<input type="text" ng-disabled="fieldDisabled" />',
        scope:{ something: '=', lol: '=ngDisabled' },
        link: function (scope, element, attrs) {
            scope.something = attrs.something;
        },
        controller: function($scope) {
            $scope.fieldDisabled = false;
            $scope.myAction = function() {
                $scope.fieldDisabled = true;
            };
        }
    }
});

请注意,唯一的变化是lol: '=ngDisabled'. 这使它起作用,因为现在您的指令知道 ngDisabled 是什么。您不必使用lol或进行任何其他特殊接线。您现在可以像使用任何其他控制器一样使用您自己的变量来使用您的控制器。

于 2016-11-08T19:00:58.643 回答