2014-09-23 42 views
-1

我有一個複選框列表,它是由一個ID數組支持的複選框。

<input type="checkbox" name="checkers" value="black" ng-model="board" /> 
<input type="checkbox" name="checkers" value="white" ng-model="board" /> 

模型將如下所示:

[ 'black', 'white' ] 

所以有許多「黑客」來得到這個工作就像人會想到,甚至一個指令checklist-model

我的問題是我有一個指令,使用ngModelController的$validators進行動態驗證。該指令看起來是這樣的:

module.directive('validator', function($parse) { 
    return { 
     restrict: 'A', 
     require: '?ngModel', 
     link: function($scope, $element, $attrs, ngModelCtrl) { 
      var rules = $parse($attrs.validator)($scope); 
      ngModelCtrl.$validators.myValidator = function(val){ 

       // this is simplified, real case is much more complex 
       if(rules.minSelections > 0){ 
        return !(val.length <= rules.minSelections); 
       } 

       if(rules.required){ 
        return !val.length; 
       } 

      } 
     } 
    } 
}); 

我連接到我的複選框,如:

<input type="checkbox" name="checkers" val="black" validators="{ minSelections: 1 }" ng-model="board" /> 
<input type="checkbox" name="checkers" val="white" validators="{ minSelections: 1 }" ng-model="board" /> 

問題是在myValidator驗證val總是返回真/假。儘管採取了幾種不同的方法,甚至使用該指令,但我似乎無法得到我需要的「實際」模型。注意:$ validator在點擊該指令之前運行。

有沒有人有任何建議?

+0

複選框是真正的/默認爲false。我不認爲'val'是一個有效的屬性。也許你需要使用ng-true-value =「black」ng-false-value =「」。我假設你實際上並不需要一個RADIO按鈕(也就是說你可以選擇黑色或者不是兩者)。目前的設置允許你選擇黑色和白色 – Scott 2014-09-23 17:51:59

+0

val是一個錯字...沒有單選按鈕...我試過真正的/虛假的交易,並沒有運氣,因爲它是屬性,不會讓我打電話給fns – amcdnl 2014-09-23 20:14:09

回答

0

我最終創建了自己的複選框指令並手動觸發驗證發生。

如果您在下面看看,您可以看到我如何看集合,並且如果值已更改,我提交該值並手動重新觸發驗證。

繼承人對他人的代碼:

define(['angular'], function (angular) { 

    // Use to style checkboxes, bind checkboxes to arrays, and run validators on checkboxes 
    // Modified from: https://github.com/bkuhl/angular-form-ui/tree/master/src/directives/checkBox 
    var module = angular.module('components.checkbox', []); 

    /** 
    * <check-box ng-model="isChecked()"></check-box> 
    * Required attribute: ng-model="[expression]" 
    * Optional attribute: value="[expression]" 
    */ 
    module.directive('checkBox', function() { 
     return { 
      replace: true, 
      restrict: 'E', 
      scope: { 
       'externalValue': '=ngModel', 
       'value': '&' 
      }, 
      require: 'ngModel', 
      template: function (el, attrs) { 
       var html = '<div class="ngCheckBox' + ((angular.isDefined(attrs.class)) ? ' class="'+attrs.class+'"' : '') + '">'+ 
        '<span ng-class="{checked: isChecked}">' + 
         '<input type="checkbox" ng-model="isChecked"' + ((angular.isDefined(attrs.id)) ? ' id="'+attrs.id+'"' : '') + '' + ((angular.isDefined(attrs.name)) ? ' name="'+attrs.name+'"' : '') + '' + ((angular.isDefined(attrs.required)) ? ' name="'+attrs.required+'"' : '') + '/>'+ 
        '</span>'+ 
       '</div>'; 
       return html; 
      }, 
      controller: function ($scope) { 
       if (angular.isArray($scope.externalValue)) { 
        $scope.isChecked = $scope.externalValue.indexOf($scope.value()) >= 0; 
       } else { 
        $scope.isChecked = !!$scope.externalValue; 
       } 

       $scope.$watch('isChecked', function (newValue, oldValue) { 
        if (angular.isDefined(newValue) && angular.isDefined(oldValue)) { 
         //add or remove items if this is an array 
         if (angular.isArray($scope.externalValue)) { 
          var index = $scope.externalValue.indexOf($scope.value()); 
          if(newValue) { 
           if(index < 0) $scope.externalValue.push($scope.value()); 
          } else { 
           if(index >= 0) $scope.externalValue.splice(index, 1); 
          } 
         } else { 
          //simple boolean value 
          $scope.externalValue = newValue; 
         } 
        } 
       }); 
      }, 
      link: function ($scope, $elm, $attrs, ngModel) { 
       $scope.$watchCollection('externalValue', function(newVal) { 
        if (newVal.length) { 
         ngModel.$setTouched(); 
         ngModel.$commitViewValue(); 
         ngModel.$validate(); 
        } 
       }); 
      } 
     }; 
    }); 

    return module; 
});