简体   繁体   中英

Angular radio ng-change works only first time

I can't understand why angular ng-change function are called only in first click. In this example

http://jsfiddle.net/ZPcSe/5/

function is called every time when i change current radio selection, but in my code something is wrong

http://jsfiddle.net/4jL3u8ko/1/

Can someone change my code to work like first example, and explain why it isn't working?

Great question.

This is not an answer but one may call this explanations to answers and any further problems that may occur. And this happens quite often, so its important to understand. The answer given by @Victor is ok and the comment of @Atias is also helpful.

Explanation -

Simple explanation : ng-repeat forms child scope.

Little detailed :

So your application has 3 scopes (or may increase depending on the number of values in $scope.radioButtons). Let me name them - parentScope(main scope), childScope1(scope of first element of ng-repeat) and childScope2(scope of second element of ng-repeat).

Parent scope variables : calledFunctions(array), radioButtons(object) and newValue(function)

ChildScope1 variables : name(assigned a literal at the start), val(assigned an object at start) and value(it has no value, or undefined)

ChildScope2 variables : name(assigned a literal at the start), val(assigned an object at start) and value(it has no value, or undefined)

What happens when you click on the radio button of childScope1(for first time):

ChildScope1.value = ChildScope1.name or ChildScope1.value= "Radio1"; the ng-change directive checks if this scope's model has been changed? Yes, as it was undefined and now it has a literal("Radio1")!! So call ChildScope1.newValue(), which obviously is not present. Therefore now look for parent- call parentScope.newValue(). This is present, so execute it.

keep in mind that ChildScope1.value= "Radio1";

After clicking on other radio buttons...... Now lets click 2nd time on ChildScope1's radio button. After clicking it- ChildScope1.value = ChildScope1.name or ChildScope1.value= "Radio1"; the ng-change directive checks if this scope's model has been changed??? No!! Because it still contains the same literal vaule as before, so do not even look for ChildScope1.newValue() or ParentScope.newValue() function.

Now same thing happens with ChildScope2.

Hope this explains why your fiddle works like a one time binding, or how @Victor or @Atias are correct.

Simply the solution is - The ng-model of ChildScope1 or ChildScope2 or any other child scopes, should point to a variable of parent scope. So you can use $parent or make an object in parent scope(main scope) with a property( eg.- ParentVal={ChildVal = ""};). And in ng-model inside ng-repeat- write ng-model=ParentVal.ChildVal.

Sorry for my poor english and please pardon my spelling mistakes if there is any.

Thanks

ng-model is tricky. You should always, always have a dot in your models, or you get this kind of problem where you are creating several models and you think you only have one.

As a quick fix, use $parent.value instead of just value in your ng-model and ng-change .

As a good fix, have a proper model object in the scope, instead of storing values directly in the scope:

$scope.model = {};

ng-model="model.radiosValue"

As an even better fix, use the controllerAs pattern and use that object as the view model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM