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;

        });
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • angular tag should be removed - it's for angular 2..4 – JGFMK Aug 13 '17 at 13:20
  • Follow the golden rule: **always put a dot in your ng-models**. Possible duplicate of [What are the nuances of scope prototypal / prototypical inheritance in AngularJS?](https://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs). – georgeawg Aug 13 '17 at 16:02

2 Answers2

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>
Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
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

Ankit
  • 5,733
  • 2
  • 22
  • 23
  • The use of `$parent` is a [code smell](https://en.wikipedia.org/wiki/Code_smell), a symptom of a deeper problem. Seek a more robust solution. – georgeawg Aug 13 '17 at 15:59
  • 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. – Ankit Aug 13 '17 at 16:13
  • The issue with primitives can be easily avoided by following the "best practice" of [always have a '.' in your ng-models](http://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m) – watch 3 minutes worth. Misko demonstrates the primitive binding issue with `ng-switch`. – georgeawg Aug 13 '17 at 17:42
  • 1
    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](https://github.com/angular/angular.js/wiki/Understanding-Scopes). – georgeawg Aug 13 '17 at 17:49
  • 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 :) – Ankit Aug 13 '17 at 18:03