Ben
Ben

Reputation: 11502

Angular: How to bind to an entire object using ng-repeat

I'm just beginning to experiment in Angular, and confused about how best to approach binding using ng-repeat. I basically get the point about ng-repeat creating a child scope. My problem is much more basic :) For html like this:

<div ng-controller="swatchCtrl" class="swatch-panel">
    Swatches
    <ul>
        <li ng-repeat="swatch in swatchArray" class="swatch">
            <input
                type="radio"
                name="swatches"
                ng-model="$parent.currentSwatch"
                value="{{swatch}}"              
            >
            <label class="swatch-label">
                <div class="swatch-color" style="background-color: #{{swatch.hexvalue}};"></div
                ><span class="swatch-name">{{swatch.colorName}}</span> 
            </label>
        </li>
    </ul>

    currentSwatch is:
    <pre>{{currentSwatch | json}}</pre>

    currentSwatchObj is:
    <pre>{{currentSwatchObj | json}}</pre>
        how do I tell this to fire??

    swatchArray is:
    <pre>{{swatchArray | json}}</pre>
</div>

and javascript like this:

function swatchCtrl($scope) {
    $scope.swatchArray = [
        {colorName:'Red', hexvalue: 'ff0000', selected: 'false'},
        {colorName:'Green', hexvalue: '00ff00', selected: 'false'},
        {colorName:'Blue', hexvalue: '0000ff', selected: 'false'}
    ];

    $scope.currentSwatch = {};
}

http://jsfiddle.net/8VWnm/

I want to:

a) When the user clicks on a radio button, I want it to set both the colorName and the hexvalue properties of the currentSwatch object. Right now the binding seems to be giving me a stringified object from the array. How do watch the return of currentSwatch so I can parse it back to an available object? Simple, I know, but what am I missing?

b) When the user clicks on a radio button, I think I want that to set the value of the corresponding "selected" key in the original array to "true". Vice versa for unchecking. Let's say that only one swatch can ever be selected at a time in the palette. (I would like in theory to be able to iterate through the array later on, on the supposition that the different keys and values are likely to sometimes not be unique.)

This kinda stuff is super easy with jquery methods, but I'd like to learn the idiomatic angular way. Thanks in advance for any help.

Upvotes: 1

Views: 3386

Answers (2)

R01010010
R01010010

Reputation: 5958

For future users that can come here to do the same in a select, you don't need use any index, the select must be done like this: http://docs.angularjs.org/api/ng.directive:select

Upvotes: 1

DanEEStar
DanEEStar

Reputation: 6280

http://jsfiddle.net/8VWnm/54/

Instead of listening to the ng-click event I would set the index of the selected element to a variable called "currentSwatchIndex"

<li ng-repeat="swatch in swatchArray" class="swatch">
    <input
        type="radio"
        ng-model="$parent.currentSwatchIndex"
        value="{{$index}}"              
    >
</li>

The you can $watch value changes of the currentSwatchIndex in your controller and set the selected swatch-Object and selection states in this $watch function:

$scope.$watch('currentSwatchIndex', function(newValue, oldValue) {
    $scope.currentSwatchObj = $scope.swatchArray[newValue];
    $scope.swatchArray[newValue].selected = true;
    $scope.swatchArray[oldValue].selected = false;
});

Only knowing the currentSwatchIndex should be enough to identify the selected swatchObject. So probably you can get rid of the currentSwatchObj and the selected property of your swatchArray. You can always get the selected swatch programmatically through a array access.

Upvotes: 2

Related Questions