Search code examples
angularjsjsonangularjs-ng-repeatangular-ngmodel

ng-repeat and user selected value in angular data binding


I have three layer json parent-child object ( Persons > Projectors > Model ). When user clicks on one of the Projector i would like to capture that value and list Model belongs to only that Projector.

HTML

<div ng-app="myApp" ng-controller="MyController">
<h4>
  Two Way Data Bind
</h4>
<lable style="color:green"> The value you picked (JSON): </lable>
{{value.val}}

</br>
<div close-others="oneAtATime">
  <uib-accordion-group ng-repeat="num in list">
      <uib-accordion-heading>
          {{ num.Title }}                                 
      </uib-accordion-heading>
        <div class="list-group"> 
          <a href="#" ng-repeat="oum in num.Projectors" ng-model="num" ng-click="value.val=num">
            <li> {{ oum.Projector }} </li>
          </a>
        </div>
  </uib-accordion-group>

  <h4>
  Listing all Models for picket Projector {{num}}: </h4>

  <uib-accordion-group ng-repeat="first in value">
    <uib-accordion-group ng-repeat="second in first.Projectors">
           {{second.Model}}
    </uib-accordion-group>
  </uib-accordion-group>

 </div>
</div>

APP.JS

angular.module('myApp', [])
    .controller('MyController', function($scope){
      $scope.value = {val:"TEST"};
      $scope.filterBy = {};

      $scope.list = [{
            "Title":"King",
          "BossName":[
                {
                    "User": "TestUSer",
                    "Name": "TestName"
                }
            ],
           "Projectors":[
                {
                    "Projector": "TestParam",
                    "Type": [
                        {
                            "Name": "TestVI"
                        }
                    ],
                    "Model": [
                        {
                            "Service": "TestSev",
                            "Notification": "TestNot"
                        }
                    ]
                },
                {
                    "Projector": "TestHouse",
                    "Type": [
                        {
                            "Name": "TestI"
                        }
                    ],
                    "Model": [
                        {
                            "Service": "TestCri",
                            "Notification": "TestOk"
                        }
                    ]
                }
             ] 
      },
      {
            "Title":"Queen",
          "BossName":[
                {
                    "User": "Liz",
                    "Name": "Nothing"
                }
            ],
           "Projectors":[
                {
                    "Projector": "PTestParam",
                    "Type": [
                        {
                            "Name": "TestVI"
                        }
                    ],
                    "Model": [
                        {
                            "Service": "TestSev",
                            "Notification": "TestNot"
                        }
                    ]
                },
                {
                    "Projector": "PTestHouse",
                    "Type": [
                        {
                            "Name": "TestI"
                        }
                    ],
                    "Model": [
                        {
                            "Service": "TestCri",
                            "Notification": "TestOk"
                        }
                    ],
                    "Model": [
                        {
                            "Service": "3TestCri",
                            "Notification": "3TestOk"
                        }
                    ]
                }
             ] 
      }
      ];

});

Problem: 1. How to capture user clicked/ picked value ? I tried data binding using ng-model on that tag but didn't work for me. 2. Now when i click on any Projector, it also list Model value for other Projector.

Demo: JFiddle


Solution

  • 1) It looks like your json is slightly wrong. It is having 2 projector model's for the last projector. Normally it should be something like

                         "Models":[
                              {
                                  "Service": "TestCri",
                                  "Notification": "TestOk"
                              },
                              {
                                  "Service": "Test43Cri",
                                  "Notification": "TestNotOk"
                              }
                          ]
    

    And then we access them in the markup as

    <uib-accordion-group ng-repeat="model in value.val.Models">
           {{model}}
    </uib-accordion-group>
    

    2) Listing all Models for picket Projector {{num}}: may not display any value for you because num will be created in the scope of ng-repeat. ng-repeat uses it's own scope. So you have to use value.val which is created in the controller's scope

    3) Once you make the above changes, you dont need

    <uib-accordion-group ng-repeat="first in value">
    

    4) <br> is correct way. </br> is wrong way. It is a self closing tag.

    So, your markup will be something like

    <div ng-app="myApp" ng-controller="MyController">
    <h4>
      Two Way Data Bind
    </h4>
    <lable style="color:green"> The value you picked (JSON): </lable>
    {{value.val}}
    
    <br>
    <div close-others="oneAtATime">
      <uib-accordion-group ng-repeat="num in list">
          <uib-accordion-heading>
              {{ num.Title }}                                 
          </uib-accordion-heading>
            <div class="list-group"> 
              <a href="#" ng-repeat="oum in num.Projectors" ng-model="oum" ng-click="value.val=oum">
                <li> {{ oum.Projector }} </li>
              </a>
            </div>
      </uib-accordion-group>
    
      <h4>
      Listing all Models for picket Projector: </h4>
        <uib-accordion-group ng-repeat="model in value.val.Models">
               {{model}}
        </uib-accordion-group>
     </div>
    </div>
    

    and your js will be something like

    angular.module('myApp', [])
        .controller('MyController', function($scope){
          $scope.value = {val:"TEST"};
          $scope.filterBy = {};
    
          $scope.list = [{
                "Title":"King",
              "BossName":[
                    {
                        "User": "TestUSer",
                        "Name": "TestName"
                    }
                ],
               "Projectors":[
                    {
                        "Projector": "TestParam",
                        "Type": [
                            {
                                "Name": "TestVI"
                            }
                        ],
                         "Models":[
                            {
                                "Service": "TestSev",
                                "Notification": "TestNot"
                            }
                        ]
                    },
                    {
                        "Projector": "TestHouse",
                        "Type": [
                            {
                                "Name": "TestI"
                            }
                        ],
                         "Models":[
                            {
                                "Service": "TestCri",
                                "Notification": "TestOk"
                            }
                        ]
                    }
                 ] 
          },
          {
                "Title":"Queen",
              "BossName":[
                    {
                        "User": "Liz",
                        "Name": "Nothing"
                    }
                ],
               "Projectors":[
                    {
                        "Projector": "PTestParam",
                        "Type": [
                            {
                                "Name": "TestVI"
                            }
                        ],
                         "Models":[
                            {
                                "Service": "TestSev",
                                "Notification": "TestNots"
                            }
                        ]
                    },
                    {
                        "Projector": "PTestHouse",
                        "Type": [
                            {
                                "Name": "TestI"
                            }
                        ],
                        "Models":[
                              {
                                  "Service": "TestCri",
                                  "Notification": "TestOk"
                              },
                              {
                                  "Service": "Test43Cri",
                                  "Notification": "TestNotOk"
                              }
                          ]
                    }
                 ] 
          }
          ];
    
    });
    

    Demo here Cheers.