【问题标题】:Angular $viewValue doesn't reflect in textbox on change eventAngular $viewValue 不会反映在更改事件的文本框中
【发布时间】:2017-08-07 03:09:21
【问题描述】:

我正在尝试实现 INR(印度卢比)到 USD(美元)货币转换器。视图应始终以 INR 显示值。但是该模型应该以美元保持价值。

为此,我实现了一个用于输入的文本框。输入将始终以 INR 给出。

我正在使用 ngModel 的 $viewValue 和 $modelValue 属性来处理我的问题。

我有一种情况,即在某些事件的后台计算货币。例如。如果货币在模型中存储为 1 美元。它在应用程序中的某些事件上更改为 2 美元。在这种情况下,我的视图以美元显示价值(在本例中为 2 美元),并且只有当我专注于我的文本框时,价值才会以 INR 显示(如 126 INR)。

$viewValue 未显示在更改事件的文本框中。

请帮帮我。

.directive('usdInrInput', function($filter, $timeout) {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, modelCtrl) {

            function conversionFunction() {
                modelCtrl.$viewValue = modelCtrl.$modelValue * 63;
                modelCtrl.$render();
            }
            element.bind("focus", function(e) {
                $timeout(function() {
                    conversionFunction();
                }, 0);
            });
            element.bind("change", function(e) {
                $timeout(function() {
                    conversionFunction();
                }, 0);
            });
            modelCtrl.$parsers.push(function(inputValue) {
                var changedOutput = parseInt(inputValue) / 63;
                modelCtrl.$setViewValue(parseInt(inputValue));
                modelCtrl.$render();
                return parseInt(changedOutput);
            });
        }
    };
})

【问题讨论】:

    标签: javascript angularjs angular-ngmodel angular-directive


    【解决方案1】:

    您应该使用scope.$watch 观察模型值的变化,如下所示:

    scope.$watch(function() {
        return modelCtrl.$modelValue;
    }, function(val) {
        conversionFunction();
    });  
    
    • 对美元汇率使用一个常数,以便在发生变化时在一处进行修改。

    • 使用$evalAsync 而不是$timeout(function(){},0)

    参考evalAsync vs timeout

    演示

    我故意在 2 秒后更改模型值,使用 $timeout 进行演示。

    angular
      .module('myApp', []);
    angular
      .module('myApp')
      .controller('MyController', MyController)
      .directive('usdInrInput', usdInrInput);
    MyController.$inject = ['$scope', '$timeout'];
    
    function MyController($scope, $timeout) {
      $scope.inr = 630;
      $timeout(function() {
        $scope.inr = 10;
      }, 2000);
    }
    
    usdInrInput.$inject = ['$filter', '$timeout'];
    
    function usdInrInput($filter, $timeout) {
      return {
        require: 'ngModel',
        link: function(scope, element, attrs, modelCtrl) {
          var cRate = 63;
          scope.$watch(function() {
            return modelCtrl.$modelValue;
          }, function(val) {
            conversionFunction();
          });
    
          function conversionFunction() {
            modelCtrl.$viewValue = modelCtrl.$modelValue * cRate;
            modelCtrl.$render();
          }
          element.bind("focus", function(e) {
            scope.$evalAsync(function() {
              conversionFunction();
            });
          });
          element.bind("change", function(e) {
            scope.$evalAsync(function() {
              conversionFunction();
            });
          });
          modelCtrl.$parsers.push(function(inputValue) {
            var changedOutput = parseInt(inputValue) / cRate;
            modelCtrl.$setViewValue(changedOutput);
            modelCtrl.$render();
            return changedOutput;
          });
        }
      };
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    
    <div ng-app="myApp" ng-controller="MyController as MC">
    
      <input type="text" ng-model="inr" usd-inr-input> {{inr}}
    </div>

    【讨论】:

      猜你喜欢
      • 2022-11-01
      • 2011-04-20
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      相关资源
      最近更新 更多