2017-04-10 152 views
0

我有一个指令取决于输入。当输入改变时,我想从角度控制器调用该指令。这是我的指示。如何从控制器调用指令

var app = angular.module('App', ['ui.bootstrap']); 

app.controller('fcController', function($scope, fcService, $uibModal) { 
    $scope.formatType = '1'; 
}); 

app.directive('fcsaNumber', function($filter) { 
    var addCommasToInteger, controlKeys, hasMultipleDecimals, isNotControlKey, isNotDigit, isNumber, makeIsValid, makeMaxDecimals, makeMaxDigits, makeMaxNumber, makeMinNumber; 
    isNumber = function(val) { 
     return !isNaN(parseFloat(val)) && isFinite(val); 
    }; 
    isNotDigit = function(which) { 
     return which < 45 || which > 57 || which === 47; 
    }; 
    controlKeys = [0, 8, 13]; 
    isNotControlKey = function(which) { 
     return controlKeys.indexOf(which) === -1; 
    }; 
    hasMultipleDecimals = function(val) { 
     return (val != null) && val.toString().split('.').length > 2; 
    }; 
    makeMaxDecimals = function(maxDecimals) { 
     var regexString, validRegex; 
     if (maxDecimals > 0) { 
      regexString = "^-?\\d*\\.?\\d{0," + maxDecimals + "}$"; 
     } else { 
      regexString = "^-?\\d*$"; 
     } 
     validRegex = new RegExp(regexString); 
     return function(val) { 
      return validRegex.test(val); 
     }; 
    }; 
    makeMaxNumber = function(maxNumber) { 
     return function(val, number) { 
      return number <= maxNumber; 
     }; 
    }; 
    makeMinNumber = function(minNumber) { 
     return function(val, number) { 
      return number >= minNumber; 
     }; 
    }; 
    makeMaxDigits = function(maxDigits) { 
     var validRegex; 
     validRegex = new RegExp("^-?\\d{0," + maxDigits + "}(\\.\\d*)?$"); 
     return function(val) { 
      return validRegex.test(val); 
     }; 
    }; 
    makeIsValid = function(options) { 
     var validations; 
     validations = []; 
     if (options.maxDecimals != null) { 
      validations.push(makeMaxDecimals(options.maxDecimals)); 
     } 
     if (options.max != null) { 
      validations.push(makeMaxNumber(options.max)); 
     } 
     if (options.min != null) { 
      validations.push(makeMinNumber(options.min)); 
     } 
     if (options.maxDigits != null) { 
      validations.push(makeMaxDigits(options.maxDigits)); 
     } 
     return function(val) { 
      var i, number, _i, _ref; 
      if (!isNumber(val)) { 
       return false; 
      } 
      if (hasMultipleDecimals(val)) { 
       return false; 
      } 
      number = Number(val); 
      for (i = _i = 0, _ref = validations.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 
       if (!validations[i](val, number)) { 
        return false; 
       } 
      } 
      return true; 
     }; 
    }; 
    addCommasToInteger = function(val) { 
     var commas, decimals, wholeNumbers; 
     decimals = val.indexOf('.') == -1 ? '.00' : val.replace(/^\d+(?=\.)/, ''); 
     wholeNumbers = val.replace(/(\.\d+)$/, ''); 
     commas = wholeNumbers.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); 
     return "" + commas + decimals.substring(0, 3); 
    }; 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     scope: { 
      options: '@fcsaNumber', 
     }, 
     link: function(scope, elem, attrs, ngModelCtrl) { 
      var isValid, options; 
      options = {}; 
      if (scope.options != null) { 
       options = scope.$eval(scope.options); 
      } 
      isValid = makeIsValid(options); 
      ngModelCtrl.$parsers.unshift(function(viewVal) { 
       var noCommasVal; 
       noCommasVal = viewVal.replace(/,/g, ''); 
       if (isValid(noCommasVal) || !noCommasVal) { 
        ngModelCtrl.$setValidity('fcsaNumber', true); 
        return noCommasVal; 
       } else { 
        ngModelCtrl.$setValidity('fcsaNumber', false); 
        return void 0; 
       } 
      }); 
      ngModelCtrl.$formatters.push(function(val) { 
       if ((options.nullDisplay != null) && (!val || val === '')) { 
        return options.nullDisplay; 
       } 
       if ((val == null) || !isValid(val)) { 
        return val; 
       } 
       ngModelCtrl.$setValidity('fcsaNumber', true); 
       val = addCommasToInteger(val.toString()); 
       if (options.key == 1) { 
        options.prepend = 'S/.'; 
       } 
       if (options.key == 2) { 
        options.prepend = '$'; 
       } 
       if (options.prepend != null) { 
        val = "" + options.prepend + val; 
       } 
       if (options.append != null) { 
        val = "" + val + options.append; 
       } 
       return val; 
      }); 
      elem.on('blur', function() { 
       var formatter, viewValue, _i, _len, _ref; 
       viewValue = ngModelCtrl.$modelValue; 
       if ((viewValue == null) || !isValid(viewValue)) { 
        return; 
       } 
       _ref = ngModelCtrl.$formatters; 
       for (_i = 0, _len = _ref.length; _i < _len; _i++) { 
        formatter = _ref[_i]; 
        viewValue = formatter(viewValue); 
       } 
       ngModelCtrl.$viewValue = viewValue; 
       return ngModelCtrl.$render(); 
      }); 
      elem.on('focus', function() { 
       var val; 
       val = elem.val(); 
       if (options.prepend != null) { 
        val = val.replace(options.prepend, ''); 
       } 
       if (options.append != null) { 
        val = val.replace(options.append, ''); 
       } 
       elem.val(val.replace(/,/g, '')); 
       return elem[0].select(); 
      }); 
      if (options.preventInvalidInput === true) { 
       return elem.on('keypress', function(e) { 
        if (isNotDigit(e.which && isNotControlKey(e.which))) { 
         return e.preventDefault(); 
        } 
       }); 
      } 
     } 
    }; 
}); 

HTML

<input type ="text" ng-model ="currency" fcsa-number="{key : {{formatType}}}"> 

这里$scope.formatType = '1';是输入。如果这个formatType改变了,那么该指令需要调用。我怎样才能从角度控制器调用该指令。

回答

0

可以使用$broadcast从控制器调用指令

.controller("ctrl", function($scope) { 
    $scope.$watch('formatType', function() { 
     $scope.$broadcast("call_dir") 
    }) 
}) 
return { 
    restrict: 'A', 
    require: 'ngModel', 
    scope: { 
     options: '@fcsaNumber', 
    }, 
    link: function(scope, elem, attrs, ngModelCtrl) { 
     var isValid, options; 
     options = {}; 
     scope.$on('call_dir', function(ev) { 
      //your code 
     }) 
    }; 
+0

好...让我试试一次。并让你回来 –

+0

我可以知道这里的ev是什么 –

+0

这是事件。默认广播发送事件作为第一个参数 –

1

你可以设置你写的链接功能内部的观察者将留意是否有需要运行的fcsa-number和组的一切变化放入一个函数并在观察者内部调用它。

link: function(scope,elem,attr,ctrl){ 
scope.$watch('options', function(){ 
    // do your stuff 
}); 
+0

可我知道这fcsaNumber将如何工作 –

+0

它并不满足我的要求 –

+0

@RakeshReddy我的不好,作为你提到的指令的隔离范围变量命名为options,'options'就是你应该关注的变化。你可以将你想调用的所有逻辑分组到一个函数中,然后调用这个监视器中的函数。它应该工作。 – 32teeths

相关问题