0

I am trying to bind an object to a radio button group. Please refer the two snippets of code in this post. The first uses ng-repeat to loop but it fails. I manually repeat the element in the second example but it works. Why does ng-repeat cause this issue?

Example 1

  angular
      .module('listParser', [])
      .factory('Item', function() {
        return function(id, name) {
          this.id = id;
          this.name = name;
        }
      })
      .controller('default', ['$scope', 'Item', function($scope, Item) {
        var collection = [];
        collection.push(new Item(0, 'Alpha'));
        collection.push(new Item(1, 'Beta'));
        
        $scope.collection = collection;
        $scope.lucky = collection[0];
      }]);
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <div ng-app="listParser" ng-controller="default">
   <div class="radio-group">
    <ul><li ng-repeat="item in collection"><input type="radio" name="group" ng-value="item" ng-model="lucky"/></li></ul>
   </div>
   <div class="description">
    {{lucky.name}}
   </div>
  </div>

Example 2

  angular
        .module('listParser', [])
        .factory('Item', function() {
          return function(id, name) {
            this.id = id;
            this.name = name;
          }
        })
        .controller('default', ['$scope', 'Item', function($scope, Item) {
          var collection = [];
          collection.push(new Item(0, 'Alpha'));
          collection.push(new Item(1, 'Beta'));
          
          $scope.collection = collection;
          $scope.lucky = collection[0];
        }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="listParser" ng-controller="default">
      <div class="radio-group">
      <ul>
        <li><input type="radio" name="group" ng-value="collection[0]" ng-model="lucky"/></li>
        <li><input type="radio" name="group" ng-value="collection[1]" ng-model="lucky"/></li>
      </ul>
      </div>
      <div class="description">
      {{lucky.name}}
      </div>
    </div>
Lordbalmon
  • 1,634
  • 1
  • 14
  • 31
  • Can you open the console ? Maybe you can check what is the error on example one. Would you mind sharing the error if there exists one? – eduardo92 May 09 '18 at 18:41
  • Use of `$parent` is a [code smell](https://en.wikipedia.org/wiki/Code_smell), a symptom of a deeper problem. If there is more than one level of inherited scope between the `ng-model` directive and the Model variable, using `$parent` will fail. – georgeawg May 09 '18 at 18:57
  • @georgeawg, thank you. Editing the question likewise (: – Lordbalmon May 09 '18 at 20:13
  • This 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 May 09 '18 at 20:23

1 Answers1

1

It doesn't work with ng-repeat, because ng-repeat does create a prototypically inherited child scope. What that means is, it creates a lucky property inside the scope on ng-repeat element, that lucky scope variable isn't available outside ng-repeat element. You could forcefully use $parent prefix before lucky variable, that will eventually help you to point lucky to parent scope. But don't do that in production code, it is considered as bad practice.

In other case it wasn't issue, because all scope were on same context, where in case of ng-repeat it wasn't.

To solve this issue from the root, you can use either Dot rule or controllerAs pattern while defining ng-model

Here is another thread explains the same thing about ng-repeat

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • I think this answers my question but could you please link an article for `dot rule` and `controllerAs` pattern? It wasn't trivial to find. I could probably look deeper and find it but it will definitely complete the answer (: – Lordbalmon May 09 '18 at 19:22
  • 1
    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 May 09 '18 at 20:20