如何从角度控制器

时间:2017-04-10 12:41:59

标签: html angularjs

我有一个取决于某些输入的指令。我希望在输入改变时从角度控制器调用该指令。这是我的指示。

 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已更改,则该指令需要调用。一位朋友建议我这个

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

但它没有手动调用我的指令。

即使我尝试过

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

1 个答案:

答案 0 :(得分:0)

您需要观察控制器中要更改的值。在您的情况下,它是formatType。 您应该尝试在隔离范围中使用此表达式:

 scope: {
    options: '=fcsaNumber',
}

如果您希望事件广播起作用,即$scope.$bradcast方法,那么请确保您的指令是范围层次结构中控制器范围的子节点。另外一种更简单的方法(但并不总是建议)是从$rootScope广播您的活动。

所以这样的事情也应该有效(使用基于事件的解决方案):

.controller("ctrl", function($scope, $rootScope) {
    $scope.$watch('formatType', function() {
        $rootScope.$broadcast("call_dir")
    })
})