Как разрешить директиву ng-disabled с изолированной областью - программирование

Как разрешить директиву ng-disabled с изолированной областью

В последнее время мне нужно сделать элемент ввода работать как с ng-disabled, так и с настраиваемой директивой, которая использует изолированную область для оценки выражения так же, как то, что делает ng-disabled, так как пользовательская директива работает нормально, но ng-disabled doesn ' t, так как он оценивает выражение только в изолированном объеме.

Пользовательская директива довольно проста:

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" />

У кого-нибудь уже есть решение для этой проблемы?

Спасибо заранее! Янни

4b9b3361

Ответ 1

У меня была эта же проблема, и самое простое решение imho. заключается в том, чтобы использовать изолированную область для наследования свойства 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'. Не проверял других

Ответ 2

В последнее время у меня была аналогичная проблема. Я хотел отключить кнопку в изолированном объеме и использовать эту красивую директиву angular ng-disabled. После некоторого копания я пришел к такому решению:

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

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

    //...
}

Чтобы оценить выражение ng-diabled вместо $scope, просто перейдите к $scope.$parent, и все ваши переменные будут доступны. Несчастливо вручную установить свойство disabled.

Ответ 3

ОК, для моего собственного вопроса над моим решением стоит изменить реализацию директивы, а не использовать изолированную область:

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

Ответ 4

Вы можете настроить двунаправленную привязку к родительской области в своем изолированном определении области. Затем добавьте часы для изолированного свойства scope. Это просто дублирует код в директиве 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);
            });
        }
    }
});

Ответ 5

Вам не нужна какая-либо сложность других ответов. Проблема в том, что ваша директива даже не знает, что 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;
            };
        }
    }
});

Но работает следующая Will:

.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 или выполнить любую другую специальную проводку. Вы можете использовать свой контроллер, как и любой другой контроллер, теперь со своими собственными переменными.