2017-03-16 90 views
0

我正在嘗試實施INR(印度盧比)美元(美元)貨幣轉換器。該視圖應始終顯示INR中的值。但該模型應該保持美元價值。

爲此,我實現了一個輸入文本框。輸入將始終以INR表示。

而我使用ngModel的$ viewValue和$ modelValue屬性來處理我的問題。

我有一種情況,貨幣在某些事件的後臺計算。例如。如果貨幣以1美元存儲在模型中。它在應用程序中的某個事件上更改爲2美元。在這種情況下,我的視圖會顯示以美元爲單位的值(在本例中爲$ 2),並且僅當我將注意力放在我的文本框上時,值才以INR顯示(如126 INR)。

$ viewValue未被顯示在change事件的文本框中。

請幫幫我。

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

回答

1

你應該小心使用scope.$watch像下面的模型值的變化:

scope.$watch(function() { 
    return modelCtrl.$modelValue; 
}, function(val) { 
    conversionFunction(); 
}); 
  • 使用恆定的美元匯率,這樣就可以在一個地方修改,如果有一個更改。

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

參見evalAsync vs timeout

演示

我特意使用$timeout用於演示目的2秒後改變了模型值。

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>