3

But I have problem when I checked radio button doesn't change ng-model="title" I changed this code a lot but I can not find a solution. Can someone help, I think there is a problem here in ng-repeat? Can someone help solve this problem? I have code:

<div class="container">
    <label data-ng-repeat="option in dbQuestion">
        <input type="radio" name="form-field"  ng-model="title" value="{{option.title}}" ng-checked="$index == 0" />
        {{option.title}}
    </label>
    <span>{{title}}</span>
</div>

__

var app = angular.module("SampleApp", []);

    app.controller("SampleAppCtrl", function($scope) {



        $scope.dbQuestion = [{
                    title: "Question 1",
                    descripton: "Description 1",
                    answers: [{
                            item1: "item1",
                            value: true
                        },
                        { item2: "item2", value: true },
                        { item3: "item3", value: true },
                        {
                            item4: "item4",
                            value: true
                        }
                    ]
                },

                {
                    title: "Question 5",
                    descripton: "Description 5",
                    answers: [{
                            item1: "item1",
                            value: true
                        },
                        { item2: "item2", value: true },
                        { item3: "item3", value: true },
                        {
                            item4: "item4",
                            value: true
                        }
                    ]
                },
            ];

            $scope.title = $scope.dbQuestion[0].title;

        });
2

2 Answers 2

2

New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.

Having a '.' in your models will ensure that prototypal inheritance is in play. So, use

<label data-ng-repeat="option in dbQuestion">
    <input type="radio" name="form-field"
           ng-model="title.selected" 
           value="{{option.title}}" 
           ng-checked="$index == 0" />
    {{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
app.controller("ctrl", function($scope) {
    $scope.title = { selected: ''};
    $scope.dbQuestion = [{ /*..*/ }];
});

For more information, see AngularJS Wiki - The Nuances of Scope Prototypal Inheritance.

The DEMO

angular.module("app", [])
.controller("ctrl", function($scope) {
     $scope.title = { selected: ''};

     $scope.dbQuestion = [{
                    title: "Question 1",
                    descripton: "Description 1",
                    answers: [{
                            item1: "item1",
                            value: true
                        },
                        { item2: "item2", value: true },
                        { item3: "item3", value: true },
                        {
                            item4: "item4",
                            value: true
                        }
                    ]
                },
                {
                    title: "Question 5",
                    descripton: "Description 5",
                    answers: [{
                            item1: "item1",
                            value: true
                        },
                        { item2: "item2", value: true },
                        { item3: "item3", value: true },
                        {
                            item4: "item4",
                            value: true
                        }
                    ]
                },
            ];


});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
  <div class="container">
    <label data-ng-repeat="option in dbQuestion">
        <input type="radio" name="form-field"
               ng-model="title.selected" 
               value="{{option.title}}" 
               ng-checked="$index == 0" />
        {{option.title}}<br>
    </label>
    <p>Selected - {{title.selected}}</p>
  </div>
</body>

Sign up to request clarification or add additional context in comments.

Comments

0

You need to use $parent.title instead of title, like this :

<input type="radio" name="form-field"  ng-model="$parent.title" value="{{option.title}}" ng-checked="$index == 0" />

ng-repeat creates its own scope and in order to assign the value to the parent scope from the child scope we need to use $parent

5 Comments

The use of $parent is a code smell, a symptom of a deeper problem. Seek a more robust solution.
Thanks for your comment :) The way i understand it is : ng-repeat creates its own scope and in order to assign the value to the parent scope from the child scope we need to use $parent , please let me know your views.
The issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
The $parent approach lacks robustness. What if the template changes to have more scopes between the controller and the ng-model directive? Binding ng-model to a property of an object will work no matter how many directives such as ng-repeat, ng-switch, ng-if, ng-view, ng-include, etc. directives intercede. For more information, see AngularJS Wiki - The Nuances of Scope Prototypal Inheritance.
Thanks for sharing :) the answer posted above is an oversimplified version only in the context of question posted. I am in absolute agreement (and little bit intimidated !) with your views regarding robustness of this solution :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.