I have a strange behavior in my app using AngularJS 1.5.8:
我在使用AngularJS 1.5.8的应用程序中有一个奇怪的行为:
plunker (https://plnkr.co/edit/zaHVJeK8hdxk2gaOL9Pf?p=preview) and video(http://recordit.co/eszvfdfC9S)
plunker(https://plnkr.co/edit/zaHVJeK8hdxk2gaOL9Pf?p=preview)和视频(http://recordit.co/eszvfdfC9S)
-
step 1. At the beginning changing
ng-required
doesn't callng-change
function -
step 2. After making changes in
input
AND removing them (input
is empty)ng-required
DOES callng-change
function
步骤1.在开始时更改ng-required不会调用ng-change功能
步骤2.在输入中进行更改并删除它们(输入为空)ng-required DOES调用ng-change功能
expected behavior?
-
step 2. After making changes in
input
AND removing them (input
is empty)ng-required
SHOULD NOT callng-change
function. As it was at the beginning, and as it is when input has some value
步骤2.在输入更改并删除它们(输入为空)后,必须不要调用ng-change功能。就像它在开始时一样,并且当输入具有某些价值时
Please let me know if it's a bug or not. If not then why changing ng-required
calls ng-change
NOT always or even at all?
如果这是一个错误,请告诉我。如果没有那么为什么更改ng-required调用ng-change并不总是甚至根本没有?
ANSWER IS FOUND-------------------------------------------------------------------------------------------------------
ANSWER FOUND ----------------------------------------------- -------------------------------------------------- ------
NgModelController has two properties: $viewValue (value entered by user) and $modelValue (value bound to your model). When the value entered by the user fails validation, NgModelController sets the model to undefined.
NgModelController有两个属性:$ viewValue(用户输入的值)和$ modelValue(绑定到模型的值)。当用户输入的值未通过验证时,NgModelController将模型设置为undefined。
In AngularJS 1.3, they added the ng-model-options directive. It lets you configure how/when the model gets updated. You can use the allowInvalid option to prevent your model from being set to undefined:
在AngularJS 1.3中,他们添加了ng-model-options指令。它允许您配置模型更新的方式/时间。您可以使用allowInvalid选项来防止将模型设置为undefined:
ng-model-options="{allowInvalid: true}"
4 个解决方案
#1
3
You should add
你应该添加
ng-model-options="{allowInvalid: true}"
So the final result will be
所以最终的结果将是
<input type="text"
ng-change="$ctrl.onChange()"
ng-required="$ctrl.isRequired"
ng-model-options="{allowInvalid: true}"
ng-model="$ctrl.val"
/>
#2
2
This is happening because the ng-required is changing the attached modal value to undefined from blank when the required is set to false, due to this ng-change is fired since the modal changes.
发生这种情况是因为当required需要设置为false时,ng-required正在将附加的模态值从空白处更改为未定义,因为此模式更改后会触发此更改。
Check in the plunker i have console.log the value of input and you can see the change of modal clearly.
检查plunker我有console.log输入的值,你可以清楚地看到模态的变化。
angular.
module('myApp', []).
component('greetUser', {
templateUrl: 'tmpl.html',
controller: function GreetUserController() {
this.output='';
this.isRequired = false;
console.log(this.val);
this.onChange = function() {
console.log(this.val);
this.output+='Changed\n';
}
}
});
plunker : https://plnkr.co/edit/6IeIjIDahcmBIU4KSASJ?p=preview
plunker:https://plnkr.co/edit/6IeIjIDahcmBIU4KSASJ?p =preview
Now the question arises that why not the on load/ first time the change event is not firing up that is because we are using this object rather then $scope.
现在出现的问题是,为什么不加载/第一次更改事件没有启动,因为我们使用的是此对象而不是$ scope。
Here 'this' vs $scope in AngularJS controllers
这是'this'与AngularJS控制器中的$ scope
is a very good example which explains why until we manually enter the value in the input at least once the change event is not firing up.
是一个非常好的例子,它解释了为什么在我们手动输入输入值至少一次更改事件未启动之前。
in short this is happening because ng-change/ng-model works with scope variables. Once you manually enter value in the input element, the model binding happens with the scope, and the ng-change event start firing up.
简而言之,这是因为ng-change / ng-model与范围变量一起使用。在输入元素中手动输入值后,模型绑定将与范围一起发生,并且ng-change事件将启动。
#3
0
I think you misunderstanding.
我觉得你误会了。
ng-required
and ng-change
is different things. doing different purpose, and not calling each other.
ng-required和ng-change是不同的东西。做不同的目的,而不是互相打电话。
ng-change
is calling your function no matter what it's empty or not. It's call your method by it self, regarding to changes happening in the input.
ng-change正在调用你的函数,无论它是否为空。关于输入中发生的变化,它会自动调用您的方法。
ng-required
is just checking value if it's empty or not, If it is empty, mark it as invalid.
ng-required只是检查值是否为空,如果为空,则将其标记为无效。
In order to get what you want, you have to check the validity inside the onChange function.
为了得到你想要的东西,你必须检查onChange函数内的有效性。
this.onChange = function() {
if( !$scope.$ctrl.form.$valid ) return;
this.output+='Changed\n';
}
#4
0
I think this is the reason. put an alert inside ng-change like this.
我想这就是原因。在这样的ng-change内部发出警报。
this.onChange = function() {
alert(this.val);
this.output+='Changed\n';
}
When you empty the box after completing it the value change between two values:
完成后清空框时,两个值之间的值会发生变化:
undefined when is required
'' when is not required
So By changing the radio box you call the ng-change, At the beginning you have
因此,通过更改收音机框,您可以调用ng-change,一开始就有
However when you have not started to type in the text box , radio box does not change the input value , because ng-change is for input. In the beginning we have undefined --> undefined
so nothing changed. then when you empty the input you have '' ---> undefined
.
但是,如果您尚未开始输入文本框,则单选框不会更改输入值,因为ng-change用于输入。一开始我们有未定义 - >未定义所以没有改变。然后当你清空输入时,你有'--->未定义。
Actually if you put this in your controller you get call ng-change at the beginning too.
实际上,如果你把它放在你的控制器中,你也可以在开始时调用ng-change。
this.val ='';
So if you replace your controller with this , you see ng-change is called even at the beginning.
因此,如果用这个替换你的控制器,你会看到甚至在开始时调用ng-change。
angular.
module('myApp', []).
component('greetUser', {
templateUrl: 'tmpl.html',
controller: function GreetUserController() {
this.output='';
this.isRequired = false;
this.val ='';
this.onChange = function() {
this.output+='Changed\n';
}
}
});
#1
3
You should add
你应该添加
ng-model-options="{allowInvalid: true}"
So the final result will be
所以最终的结果将是
<input type="text"
ng-change="$ctrl.onChange()"
ng-required="$ctrl.isRequired"
ng-model-options="{allowInvalid: true}"
ng-model="$ctrl.val"
/>
#2
2
This is happening because the ng-required is changing the attached modal value to undefined from blank when the required is set to false, due to this ng-change is fired since the modal changes.
发生这种情况是因为当required需要设置为false时,ng-required正在将附加的模态值从空白处更改为未定义,因为此模式更改后会触发此更改。
Check in the plunker i have console.log the value of input and you can see the change of modal clearly.
检查plunker我有console.log输入的值,你可以清楚地看到模态的变化。
angular.
module('myApp', []).
component('greetUser', {
templateUrl: 'tmpl.html',
controller: function GreetUserController() {
this.output='';
this.isRequired = false;
console.log(this.val);
this.onChange = function() {
console.log(this.val);
this.output+='Changed\n';
}
}
});
plunker : https://plnkr.co/edit/6IeIjIDahcmBIU4KSASJ?p=preview
plunker:https://plnkr.co/edit/6IeIjIDahcmBIU4KSASJ?p =preview
Now the question arises that why not the on load/ first time the change event is not firing up that is because we are using this object rather then $scope.
现在出现的问题是,为什么不加载/第一次更改事件没有启动,因为我们使用的是此对象而不是$ scope。
Here 'this' vs $scope in AngularJS controllers
这是'this'与AngularJS控制器中的$ scope
is a very good example which explains why until we manually enter the value in the input at least once the change event is not firing up.
是一个非常好的例子,它解释了为什么在我们手动输入输入值至少一次更改事件未启动之前。
in short this is happening because ng-change/ng-model works with scope variables. Once you manually enter value in the input element, the model binding happens with the scope, and the ng-change event start firing up.
简而言之,这是因为ng-change / ng-model与范围变量一起使用。在输入元素中手动输入值后,模型绑定将与范围一起发生,并且ng-change事件将启动。
#3
0
I think you misunderstanding.
我觉得你误会了。
ng-required
and ng-change
is different things. doing different purpose, and not calling each other.
ng-required和ng-change是不同的东西。做不同的目的,而不是互相打电话。
ng-change
is calling your function no matter what it's empty or not. It's call your method by it self, regarding to changes happening in the input.
ng-change正在调用你的函数,无论它是否为空。关于输入中发生的变化,它会自动调用您的方法。
ng-required
is just checking value if it's empty or not, If it is empty, mark it as invalid.
ng-required只是检查值是否为空,如果为空,则将其标记为无效。
In order to get what you want, you have to check the validity inside the onChange function.
为了得到你想要的东西,你必须检查onChange函数内的有效性。
this.onChange = function() {
if( !$scope.$ctrl.form.$valid ) return;
this.output+='Changed\n';
}
#4
0
I think this is the reason. put an alert inside ng-change like this.
我想这就是原因。在这样的ng-change内部发出警报。
this.onChange = function() {
alert(this.val);
this.output+='Changed\n';
}
When you empty the box after completing it the value change between two values:
完成后清空框时,两个值之间的值会发生变化:
undefined when is required
'' when is not required
So By changing the radio box you call the ng-change, At the beginning you have
因此,通过更改收音机框,您可以调用ng-change,一开始就有
However when you have not started to type in the text box , radio box does not change the input value , because ng-change is for input. In the beginning we have undefined --> undefined
so nothing changed. then when you empty the input you have '' ---> undefined
.
但是,如果您尚未开始输入文本框,则单选框不会更改输入值,因为ng-change用于输入。一开始我们有未定义 - >未定义所以没有改变。然后当你清空输入时,你有'--->未定义。
Actually if you put this in your controller you get call ng-change at the beginning too.
实际上,如果你把它放在你的控制器中,你也可以在开始时调用ng-change。
this.val ='';
So if you replace your controller with this , you see ng-change is called even at the beginning.
因此,如果用这个替换你的控制器,你会看到甚至在开始时调用ng-change。
angular.
module('myApp', []).
component('greetUser', {
templateUrl: 'tmpl.html',
controller: function GreetUserController() {
this.output='';
this.isRequired = false;
this.val ='';
this.onChange = function() {
this.output+='Changed\n';
}
}
});