使用 ng-change 更新 AngularJS 模型会导致一个字段在更新时变为空
Updating AngularJS model with ng-change causes one field to become null when updating
在 3 个单独的字段上同时更新 AngularJS 模型值会导致一个字段在 ng-change 上变为空。
我在使用 ng-change 时遇到了一些奇怪的行为。我拥有的是 3 个独立的领域,它们都集成在一起。一个是基本贷款金额,一个是 属性 的估计值,最后一个是贷款价值比。当输入基本贷款金额和估计值的值时,将计算贷款价值比率。然后,如果用户决定更改贷款与价值比率,则重新计算基本贷款金额 and/or 估计值,依此类推。
到目前为止,我的逻辑符合预期。我输入一个基本贷款金额,然后输入一个估计值,然后计算出贷款价值比。但是,一旦计算出该值,基本贷款金额字段就会清空并变为空。
我不确定为什么会这样,我尝试了 ng-blur 和 ng-change,但得到了相同的结果。我已经在 Chrome 中调试了几个小时。
我已经提供了我正在使用的 html 以及我控制器中的操作逻辑。
谢谢
HTML内容
<div class="form-content">
<form name="priceSearch" novalidate>
<!-- Row 1 -->
<div class="form-row">
<!-- The LTV (Loan-To-Value) ratio is calculated as the amount of the mortgage lien divided by the appraised value of the property, expressed as a percentage. -->
<div class="form-group col-md-3">
<!--if user enters loan amount, update LTV-->
<label for="baseLoanAmt">Base Loan Amount</label>
<input name="baseLoanAmt" class="form-control form-control-sm" type="number" placeholder="0.00" ng-step="any" ng-model="pricer.baseLoanAmount" ng-required="true" aria-describedby="blaHelpInline" ng-change="updateBaseLoanAmtEstValLTV('baseLoanAmt', pricer.baseLoanAmount)" ng-model-options="{debounce: {default: 400, blur: 0}}">
</div>
<div class="form-group col-md-3">
<label for="estimatedVal">Estimated Value</label>
<input name="estimatedVal" class="form-control form-control-sm" type="number" placeholder="0.00" step="any" ng-model="pricer.appraisedEstimatedValue" ng-required="true" aria-describedby="estValHelpInline" ng-change="updateBaseLoanAmtEstValLTV('estimatedVal', pricer.appraisedEstimatedValue)" ng-model-options="{debounce: {default: 400, blur: 0}}">
</div>
<div class="form-group col-md-3">
<!--if user enters LTV, update base loan amount-->
<label for="ltvRatio">LTV</label>
<input name="ltvRatio" class="form-control form-control-sm" type="number" ng-step="any" ng-model="pricer.ltvRatio" ng-change="updateBaseLoanAmtEstValLTV('ltvRatio', pricer.ltvRatio)" ng-model-options="{debounce: {default: 400, blur: 0}}" ng-pattern="/^\d+(\.\d{1,2})?$/">
</div>
<div class="form-group col-md-3">
<label>Loan Purpose</label>
<select class="form-control form-control-sm" ng-model="pricer.loanInformation.loanPurpose" ng-options="obj.val as obj.key for obj in loanPurposeOptions" ng-required="true">
</select>
</div>
</div>
<!-- End Row 1 -->
</form>
</div>
控制器逻辑
app.controller('pricingSearch', ["$scope", "$rootScope", "$q", "dal", "$http", "$timeout", "$filter", function ($scope, $root, $q, _dal, $http, $timeout, $filter) {
// Precision Round function
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
$scope.pricer = {
"baseLoanAmount": 0,
"appraisedEstimatedValue": 0,
"ltvRatio": 0,
"fico": 700,
"debtToIncomeRatio": 15.0,
"waiveEscrows": false,
"loanType": "Conforming",
"loanTerms": {
"ThirtyYear": true
}
};
$scope.updateBaseLoanAmtEstValLTV = function (fieldName, value) {
var findBaseLoanAmtRatio = ($scope.pricer.appraisedEstimatedValue * $scope.pricer.ltvRatio) /10;
var findEstimatedValRatio = ($scope.pricer.baseLoanAmount * $scope.pricer.ltvRatio) / 10;
var findLtvRatio = ($scope.pricer.baseLoanAmount / $scope.pricer.appraisedEstimatedValue) * 10;
console.log('The fieldName is: ' + (fieldName));
console.log('The value is: ' + (value));
if (fieldName !== 'baseLoanAmt' && value != null) {
console.log('Fire 1');
$scope.pricer.baseLoanAmount = precisionRound(findBaseLoanAmtRatio, 2);
}
if (fieldName !== 'estimatedVal' && value != null) {
console.log('Fire 2');
$scope.pricer.appraisedEstimatedValue = precisionRound(findEstimatedValRatio, 2);
}
if (fieldName !== 'ltvRatio' && value != null) {
console.log('Fire 3');
$scope.pricer.ltvRatio = precisionRound(findLtvRatio, 3);
}
};
}]);
https://plnkr.co/edit/BFlvshCp1Rhs6WpxrjmN?p=preview
这可能是因为在您的代码中的某些地方您除以零。
除非您首先检查它不是零,否则永远不要除以它。
function calcLtv() {
var findLtvRatio;
if($scope.pricer.appraisedEstimatedValue === 0) {
findLtvRatio = 0;
}
else {
findLtvRatio = ($scope.pricer.baseLoanAmount / $scope.pricer.appraisedEstimatedValue) * 10;
}
return findLtvRatio;
}
好的,我已经解决了我遇到的问题。首先,我必须设置一个系统来告诉 angular 计算正在进行,然后计算停止。
然后我对字段值做了一些额外的检查,确保它们没有被零除。我还添加了一些时间来完成计算,这样它们就不会完成得太快。
感谢 Pop-A-Stash 指出对我来说显而易见的事情。
可以在 this plunkr
找到更新的源
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
// Precision Round function
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
$scope.pricer = {
"baseLoanAmount": 0,
"appraisedEstimatedValue": 0,
"ltvRatio": 0
};
$scope.recalculateLoanVals = function(fieldName, value) {
var findBaseLoanAmtRatio = $scope.pricer.appraisedEstimatedValue * $scope.pricer.ltvRatio;
var findEstimatedValRatio = $scope.pricer.baseLoanAmount * $scope.pricer.ltvRatio;
var findLtvRatio = $scope.pricer.baseLoanAmount / $scope.pricer.appraisedEstimatedValue;
if ($scope.calculating) {
// console.log('Calculating...');
// console.log('The field name is: ', fieldName);
// console.log('The value is: ', value);
if (($scope.pricer.baseLoanAmount > 0) && ($scope.pricer.appraisedEstimatedValue > 0) && (fieldName !== 'ltvRatio')) {
// console.log('Just baseLoanAmt and estimatedVal are not equal to zero');
// console.log('Calculating is: ', $scope.calculating);
$timeout(function() {
$scope.pricer.ltvRatio = precisionRound(findLtvRatio, 2);
}, 1000);
}
if (($scope.pricer.baseLoanAmount > 0) && ($scope.pricer.appraisedEstimatedValue > 0) && ($scope.pricer.ltvRatio > 0) && fieldName !== 'baseLoanAmt') {
// console.log('All three are not equal to zero');
$scope.pricer.ltvRatio = value;
$timeout(function() {
$scope.pricer.baseLoanAmount = precisionRound(findBaseLoanAmtRatio, 0);
}, 1000);
}
return;
}
$scope.calculating = true;
$timeout(function() {
// console.log('No longer calculating!');
$scope.calculating = false;
}, 1200);
};
});
在 3 个单独的字段上同时更新 AngularJS 模型值会导致一个字段在 ng-change 上变为空。
我在使用 ng-change 时遇到了一些奇怪的行为。我拥有的是 3 个独立的领域,它们都集成在一起。一个是基本贷款金额,一个是 属性 的估计值,最后一个是贷款价值比。当输入基本贷款金额和估计值的值时,将计算贷款价值比率。然后,如果用户决定更改贷款与价值比率,则重新计算基本贷款金额 and/or 估计值,依此类推。
到目前为止,我的逻辑符合预期。我输入一个基本贷款金额,然后输入一个估计值,然后计算出贷款价值比。但是,一旦计算出该值,基本贷款金额字段就会清空并变为空。
我不确定为什么会这样,我尝试了 ng-blur 和 ng-change,但得到了相同的结果。我已经在 Chrome 中调试了几个小时。
我已经提供了我正在使用的 html 以及我控制器中的操作逻辑。
谢谢
HTML内容
<div class="form-content">
<form name="priceSearch" novalidate>
<!-- Row 1 -->
<div class="form-row">
<!-- The LTV (Loan-To-Value) ratio is calculated as the amount of the mortgage lien divided by the appraised value of the property, expressed as a percentage. -->
<div class="form-group col-md-3">
<!--if user enters loan amount, update LTV-->
<label for="baseLoanAmt">Base Loan Amount</label>
<input name="baseLoanAmt" class="form-control form-control-sm" type="number" placeholder="0.00" ng-step="any" ng-model="pricer.baseLoanAmount" ng-required="true" aria-describedby="blaHelpInline" ng-change="updateBaseLoanAmtEstValLTV('baseLoanAmt', pricer.baseLoanAmount)" ng-model-options="{debounce: {default: 400, blur: 0}}">
</div>
<div class="form-group col-md-3">
<label for="estimatedVal">Estimated Value</label>
<input name="estimatedVal" class="form-control form-control-sm" type="number" placeholder="0.00" step="any" ng-model="pricer.appraisedEstimatedValue" ng-required="true" aria-describedby="estValHelpInline" ng-change="updateBaseLoanAmtEstValLTV('estimatedVal', pricer.appraisedEstimatedValue)" ng-model-options="{debounce: {default: 400, blur: 0}}">
</div>
<div class="form-group col-md-3">
<!--if user enters LTV, update base loan amount-->
<label for="ltvRatio">LTV</label>
<input name="ltvRatio" class="form-control form-control-sm" type="number" ng-step="any" ng-model="pricer.ltvRatio" ng-change="updateBaseLoanAmtEstValLTV('ltvRatio', pricer.ltvRatio)" ng-model-options="{debounce: {default: 400, blur: 0}}" ng-pattern="/^\d+(\.\d{1,2})?$/">
</div>
<div class="form-group col-md-3">
<label>Loan Purpose</label>
<select class="form-control form-control-sm" ng-model="pricer.loanInformation.loanPurpose" ng-options="obj.val as obj.key for obj in loanPurposeOptions" ng-required="true">
</select>
</div>
</div>
<!-- End Row 1 -->
</form>
</div>
控制器逻辑
app.controller('pricingSearch', ["$scope", "$rootScope", "$q", "dal", "$http", "$timeout", "$filter", function ($scope, $root, $q, _dal, $http, $timeout, $filter) {
// Precision Round function
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
$scope.pricer = {
"baseLoanAmount": 0,
"appraisedEstimatedValue": 0,
"ltvRatio": 0,
"fico": 700,
"debtToIncomeRatio": 15.0,
"waiveEscrows": false,
"loanType": "Conforming",
"loanTerms": {
"ThirtyYear": true
}
};
$scope.updateBaseLoanAmtEstValLTV = function (fieldName, value) {
var findBaseLoanAmtRatio = ($scope.pricer.appraisedEstimatedValue * $scope.pricer.ltvRatio) /10;
var findEstimatedValRatio = ($scope.pricer.baseLoanAmount * $scope.pricer.ltvRatio) / 10;
var findLtvRatio = ($scope.pricer.baseLoanAmount / $scope.pricer.appraisedEstimatedValue) * 10;
console.log('The fieldName is: ' + (fieldName));
console.log('The value is: ' + (value));
if (fieldName !== 'baseLoanAmt' && value != null) {
console.log('Fire 1');
$scope.pricer.baseLoanAmount = precisionRound(findBaseLoanAmtRatio, 2);
}
if (fieldName !== 'estimatedVal' && value != null) {
console.log('Fire 2');
$scope.pricer.appraisedEstimatedValue = precisionRound(findEstimatedValRatio, 2);
}
if (fieldName !== 'ltvRatio' && value != null) {
console.log('Fire 3');
$scope.pricer.ltvRatio = precisionRound(findLtvRatio, 3);
}
};
}]);
https://plnkr.co/edit/BFlvshCp1Rhs6WpxrjmN?p=preview
这可能是因为在您的代码中的某些地方您除以零。 除非您首先检查它不是零,否则永远不要除以它。
function calcLtv() {
var findLtvRatio;
if($scope.pricer.appraisedEstimatedValue === 0) {
findLtvRatio = 0;
}
else {
findLtvRatio = ($scope.pricer.baseLoanAmount / $scope.pricer.appraisedEstimatedValue) * 10;
}
return findLtvRatio;
}
好的,我已经解决了我遇到的问题。首先,我必须设置一个系统来告诉 angular 计算正在进行,然后计算停止。
然后我对字段值做了一些额外的检查,确保它们没有被零除。我还添加了一些时间来完成计算,这样它们就不会完成得太快。
感谢 Pop-A-Stash 指出对我来说显而易见的事情。
可以在 this plunkr
找到更新的源var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
// Precision Round function
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
$scope.pricer = {
"baseLoanAmount": 0,
"appraisedEstimatedValue": 0,
"ltvRatio": 0
};
$scope.recalculateLoanVals = function(fieldName, value) {
var findBaseLoanAmtRatio = $scope.pricer.appraisedEstimatedValue * $scope.pricer.ltvRatio;
var findEstimatedValRatio = $scope.pricer.baseLoanAmount * $scope.pricer.ltvRatio;
var findLtvRatio = $scope.pricer.baseLoanAmount / $scope.pricer.appraisedEstimatedValue;
if ($scope.calculating) {
// console.log('Calculating...');
// console.log('The field name is: ', fieldName);
// console.log('The value is: ', value);
if (($scope.pricer.baseLoanAmount > 0) && ($scope.pricer.appraisedEstimatedValue > 0) && (fieldName !== 'ltvRatio')) {
// console.log('Just baseLoanAmt and estimatedVal are not equal to zero');
// console.log('Calculating is: ', $scope.calculating);
$timeout(function() {
$scope.pricer.ltvRatio = precisionRound(findLtvRatio, 2);
}, 1000);
}
if (($scope.pricer.baseLoanAmount > 0) && ($scope.pricer.appraisedEstimatedValue > 0) && ($scope.pricer.ltvRatio > 0) && fieldName !== 'baseLoanAmt') {
// console.log('All three are not equal to zero');
$scope.pricer.ltvRatio = value;
$timeout(function() {
$scope.pricer.baseLoanAmount = precisionRound(findBaseLoanAmtRatio, 0);
}, 1000);
}
return;
}
$scope.calculating = true;
$timeout(function() {
// console.log('No longer calculating!');
$scope.calculating = false;
}, 1200);
};
});