AngularJS -- creating a custom databinding and ng-repeat

I'm trying to create a custom controller that shows a bunch of similar objects that are bound to a data set like the following:

[{name: card1, values: {opt1: 9, opt2: 10}},{name: card1, values: {opt1: 9, opt2: 10}}]

I'd like to show the name and one of the values for-each card (represented as a square for each on the screen), with only one value shown depending on whether the user clicks on a button for option 1 or option 2. I'm stuck on how to change the value shown when using an ng-repeat.

html code:

<div ng-controller="aggViewport" >
<div class="btn-group">
    <button class="btn active">opt1</button>
    <button class="btn">opt2</button>
</div>
<div id="container" iso-grid width="500px" height="500px">
    <div ng-repeat="card in cards" class="item {{card.class}}">
        <table width="100%">
            <tr>
                <td align="center">
                    <h4>{{card.name}}</h4>
                </td>
            </tr>
            <tr>
                <td align="center"><h2>{{card.opt1}}</h2></td>
            </tr>
        </table>        
    </div>
</div>

controller:

module.controller('aggViewport',['$scope','$location',function($scope,$location){
$scope.cards = [{name: card1, values: {opt1: 9, opt2: 10}},{name: card1, values: {opt1: 9, opt2: 10}}];


}]);

Here is a possible solution to your problem

<div ng-controller="aggViewport" >
<div class="btn-group" >
    <button ng-click="setOption(opt.name)" ng-repeat="opt in optList" class="btn active">{{opt.name}}</button>
</div>
<div id="container" iso-grid width="500px" height="500px">
    <div ng-repeat="card in cards" class="item {{card.class}}" ng-controller="aggCardController">
        <table width="100%">
            <tr>
                <td align="center">
                    <h4>{{card.name}}</h4>
                </td>
            </tr>
            <tr>
                <td align="center"><h2>{{getOption()}}</h2></td>
            </tr>
        </table>        
    </div>
</div>

And in your controller :

module.controller('aggViewport',['$scope','$location',function($scope,$location){
$scope.cards = [{name: card1, values: {opt1: 9, opt2: 10}},{name: card1, values: {opt1: 9, opt2: 10}}];

$scope.option = "opt1";

$scope.setOption = function(val){
$scope.option = val;
}

}]);

module.controller('aggCardController',['$scope',function($scope){

$scope.getOption = function(){
return $scope.card.values[$scope.option];
}

}]);

Just to explain what is happening here. THe aggCardController is defined separately because a new scope is created when you use a ng-repeat. Also, when you introduce a controller with an ng-repeat you create the controller which will control that scope. So now you can access each scope individually. And a new controller will be created for each of the scopes created. Since in the html, the aggCardController comes inside of the aggViewPort it will inherit properties from the parent scope. So if you declare option in aggViewPort it will get inherited into all the child scopes.

The reason for introducing this new controller here is because of this statement

return $scope.card.values[$scope.option];

Since we are trying to access $scope.card here and remember that card is a new variable created in the repeater. This new variable is only available in the child scopes created by the repeater. If you did not need to access $scope.card then we could have as well written this getOption() function in the parent scope.

Also note that all objects in javascript are assciative arrays. This is the reason why we are using the array access operator [] to access the value in opt1 or opt2.

Hope this helps.