0

我以前写过这个[question] [1],Inow我有问题,模型$ viewValue与我在输入框中看到的值不一样。

<div amount-input-currency="" ng-model="data.amount" ></div> 

这是我的指令(ISNUMERIC和类似不重要的作品WEEL):

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 
    $scope.data = { amount: ''}; 
}); 
app.directive('amountInputCurrency', function() {    
    return { 
    restrict: 'EA', 
    require: 'ngModel', 
    templateUrl: 'inputCurrency.tmpl.html', 
    scope: { 
     model: '=ngModel', 
    }, 
    link: function (scope, elem, attrs, ngModelCtrl) { 
     scope.model2 = ngModelCtrl; 
     console.log("I am in the directive!"); 
     var myAmountCurrencyType = elem.find('.cb-amount-input-currency'); 

     scope.onFocus = function() { 
      removeThousandSeparator(); 
     }; 

     scope.onBlur = function() { 
      renderValue(); 
      ngModelCtrl.$render(); 
     }; 


     //format text going to user (model to view) 
     ngModelCtrl.$formatters.push(function(value) { 
     return parseValue(value); 
     }); 

     //format text from the user (view to model) 
     ngModelCtrl.$parsers.push(function(value) { 
     var num = Number(value); 
     if(isNumeric(num)) { 
      var decimal = 2; 
      return formatAmount(); 
     } else { 
      return value; 
     } 
     }); 

     function isNumeric(val) { 
     return Number(parseFloat(val))==val; 
     } 

    } 
    } 
}); 

这是我的模板:

scope.model: {{model}}<br> 
viewValue: {{model2.$viewValue}}<br> 
modelValue: {{model2.$modelValue}}<br> 
<input type="text" class="amount-input-currency form-control" x-ng-model="model" ng-focus="onFocus()" ng-blur="onBlur()"></input> 

回答

0

使用ngModelCtrl.$setViewValue()设置viewValue以更新模型,而不是直接设置$ viewValue字段。但我不确定在这种情况下使用NgModelController的意义。

如果唯一的目的是格式化文本框的值,请操作输入元素值而不是NgModelController字段。

function renderValue() { 
    var myAmountCurrencyType = elem.find('input'); 
    var value = myAmountCurrencyType.val(); 

    var decimal = 2; 
    if (value != undefined && value !="") { 
     myAmountCurrencyType.val(formatAmount()); 
    } 
    } 

这样它不会更新模型。如果您想完全控制数据绑定,可以考虑从输入元素x-ng-model="model"中删除绑定,并在您的伪指令中使用NgModelController实现它。

+0

嗨,谢谢...重点在于当我不在输入字段时(例如1.000.000,00)格式化良好的货币值,当我有焦点时删除千分...更改第62行和第86行与$ setViewValue()onBlur事件的值在范围,viewValue和modelValue中相同(我想在viewValue中有一个格式良好的值,但不在范围和模型中)。 – Hazlo8

+0

好的。现在我明白了。我相应地改变了我的答案 –

0

如果你可以在没有格式化器和解析器的情况下执行你所需要做的事情,那么它会更好,因为你的工作方式更具有角度,如果你可以避免在指令中需要ng-model,很多烂摊子也是。

至于你的问题,我会展示一个解决方案,不需要格式化器和解析器,我希望这是你想要的,如果你必须使用格式化器和解析器,你可以,但它基本上会做同样的下列溶液:

的index.html:

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="http://code.angularjs.org/1.2.15/angular.js" data-semver="1.2.15"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <!--<div amount-input-currency="" ng-model="data.amount" ></div>--> 
    <amount-input-currency model="data.amount"></amount-input-currency> 
    </body> 

</html> 

amountInputCurrency.tmpl.html:

scope.model: {{model}}<br> 
viewValue: {{model2.$viewValue}}<br> 
modelValue: {{model2.$modelValue}}<br> 
<input type="text" class="cb-amount-input-currency form-control" ng-model="model" ng-focus="onFocus()" ng-blur="onBlur()"> 

app.js:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 
    $scope.data = { amount: ''}; 
}); 
app.directive('amountInputCurrency', function() { 
    var isAllowedKey = function (k, v) { 
     return (
      k === 8 || k === 9 || k === 46 || 
      (k > 47 && k < 58) || 
      (k > 95 && k < 106) || 
      (k > 36 && k < 41) || 
      (k === 188 && (!v || v.search(/(\.|\,)/)<0)) || 
      ((k === 190 || k === 110) && (!v || v.search(/(\.|\,)/)<0)) 
    ); 
    }; 

    return { 
    restrict: 'E', 
    // require: 'ngModel', 
    templateUrl: 'amountInputCurrency.tmpl.html', 
    scope: { 
     model: '=', 
    }, 
    link: function (scope, elem, attrs) { 
     // scope.model2 = ngModelCtrl; 
     console.log("I am in the directive!"); 
     var myAmountCurrencyType = elem.find('.cb-amount-input-currency'); 
     myAmountCurrencyType.on('keydown', function (e) { 
      //if (!isAllowedKey(e.which, scope.model)) { 
      if (!isAllowedKey(e.which, scope.model)) { 
       e.preventDefault(); 
      } 
     }); 

     scope.onFocus = function() { 
      removeThousandSeparator(); 
     }; 

     scope.onBlur = function() { 
      renderValue(); 
      // ngModelCtrl.$render(); 
      // scope.model = ngModelCtrl.$viewValue; 
     }; 


     // //format text going to user (model to view) 
     // ngModelCtrl.$formatters.push(function(value) { 
     // return parseValue(value); 
     // }); 

     // //format text from the user (view to model) 
     // ngModelCtrl.$parsers.push(function(value) { 
     // var num = Number(value); 
     // if(isNumeric(num)) { 
     //  var decimal = 2; 
     //  return formatAmount(Number(num).toFixed(decimal), decimal, ',', '.'); 
     // } else { 
     //  return value; 
     // } 
     // }); 

     function isNumeric(val) { 
     return Number(parseFloat(val))==val; 
     } 

     function renderValue() { 
     var value = String(scope.model || ''); 
     var decimal = attrs.cbAmountDecimal || 2; 
     if (value != undefined && value !="") { 
      scope.model = formatAmount(value, decimal, ',', '.'); 
      // ngModelCtrl.$render(); 
     } 
     } 

     function formatAmount(amount, c, d, t) { 
     if (amount.indexOf(',') !== -1) { 
      if (amount.indexOf('.') !== -1) { 
       amount = amount.replace(/\./g,''); //remove thousand separator 
      } 
      amount = amount.replace(/\,/g,'.'); 
     } 
     c = isNaN(c = Math.abs(c)) ? 2 : c; 
     d = d === undefined ? "." : d; 
     t = t === undefined ? "," : t; 
     var n = amount, 
      s = n < 0 ? "-" : "", 
      i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", 
      j = (j = i.length) > 3 ? j % 3 : 0; 
     return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); 
     } 

     function removeThousandSeparator() { 
     if(scope.model != undefined && scope.model !="") { 
      scope.model = scope.model.replace(/\./g,''); 
      // ngModelCtrl.$render(); 
      // scope.model = ngModelCtrl.$viewValue; 
     } 
     } 

     function parseValue(viewValue) { 
     var num = 0; 
     if(isNumeric(viewValue)) { 
      num = viewValue; 
     } else { 
      num = viewValue ? viewValue.replace(/,/g,'.') : viewValue; 
     } 
     return num; 
     } 

    } 
    } 
}); 

如果这不是你想要的,那么我真的很抱歉,请评论我的解决方案中存在什么问题,我会尽我所能去看看我能否提供帮助。

+0

如果他想对其指令进行一些表单验证呢?继续使用ngModel进行操作,您只需钩住角度NgModelController的生命周期,并使您的指令/组件与角度表单系统兼容。 – Disfigure