2012-12-24 42 views
14

最近,我不得不讓一個Input元素同時使用ng-disabled和一個自定義指令,它們使用隔離範圍來評估表達式,就像ng-disabled在做什麼一樣,自定義指令工作正常,但ng-disabled沒有,因爲它只評估隔離範圍內的表達式。如何讓ng禁用的指令在隔離範圍內工作

自定義指令非常簡單,如:

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

有人已經爲這個問題的解決方案?

在此先感謝! 雅尼

+0

你能爲你的問題創建一個jsfiddle嗎? –

+0

誰在低估答案?對於基督人而言,低估是因爲不安全和嚴重的概念錯誤......至少和其他人一樣,我知道嚴重的概念錯誤...... – BradChesney79

回答

2

OK,對我自己來說我上面的解決辦法是改變指令的執行,不再使用分離範圍:

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

我最近也有類似的問題。我想在隔離範圍內禁用一個按鈕,並使用這個不錯的角度ng-disabled指令。 一些挖後,我來到了這樣一個解決方案:

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

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

    //... 
} 

爲了評估ng-diabled表達,而不是僅僅$scope跳轉到$scope.$parent和所有的變量將是avaliable。不幸手動設置禁用的屬性是必需的。

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

我有同樣的問題,最簡單的解決方案恕我直言。是使用隔離範圍來繼承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'。沒有測試過其他人

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或進行任何其他特殊佈線。您可以像現在使用您自己的變量的其他控制器一樣使用您的控制器。