r3plica
r3plica

Reputation: 13367

AngularJS get property dynamically

This should be a really simple question. Is it possible to get a property value dynamically like this:

<div tabset>
    <div tab ng-repeat="item in teamController.range track by $index">
        <div tab-heading>
            <div class="selected-colour" ng-class="{ 'no-colour-selected': !controller.kit['colour' + $index + 1] }" ng-style="{ 'background-color' : '#' + controller.kit['colour' + $index + 1] }"></div> {{ controller.kit['colour' + $index + 1] }}
        </div>

        <div class="picker colour-picker">
            <ul class="picker-dropdown list-inline">
                <li ng-repeat="colour in teamController.colours" ng-class="{ 'active': controller.kit['colour' + $index + 1] === colour.hex }">
                    <a href style="background-color: #{{ colour.hex }};" ng-click="teamController.setColour(controller.kit['colour' + $index + 1], colour)"></a>
                </li>
            </ul>
        </div>
    </div>
</div>

hopefully you can see that my model has 3 properties:

Colour1

Colour2

Colour3

And in my repeat I am trying to get each of them by doing

controller.kit['colour' + $index + 1]

Update

So I have changed my view to this:

<div tabset>
    <div tab ng-repeat="item in teamController.range track by $index">
        <div tab-heading>
            <div class="selected-colour" ng-class="{ 'no-colour-selected': !controller.kit['colour' + ($index + 1)] }" ng-style="{ 'background-color' : '#' + controller.kit['colour' + ($index + 1)] }"></div> {{ controller.kit['colour' + ($index + 1)] }}
        </div>

        <div class="picker colour-picker">
            <ul class="picker-dropdown list-inline">
                <li ng-repeat="colour in teamController.colours" ng-class="{ 'active': controller.kit['colour' + ($index + 1)] === colour.hex }">
                    <a href style="background-color: #{{ colour.hex }};" ng-click="teamController.setColour(controller.kit['colour' + ($parent.$index + 1)], colour)"></a>
                </li>
            </ul>
        </div>
    </div>
</div>

In my controller I have this:

// Set our colours
self.setColour = function (item, colour) {

    // Set the colour
    item = colour.hex;

    console.log(item);
    console.log(kit);

    // Store our model in the session
    configuratorService.saveToSession(kit);
};

It doesn't update the kit. But if I change the setColour invocation to

teamController.setColour(controller.kit['colour' + ($parent.$index + 1)], colour)

and then change my controller function to this:

// Set our colours
self.setColour = function (item, colour) {

    // Set the colour
    item.colour1 = colour.hex;

    console.log(item);
    console.log(kit);

    // Store our model in the session
    configuratorService.saveToSession(kit);
};

everything works fine. I have also tried using teamController.setColour(controller.kit['colour' + ($index + 1)], colour) and this didn't work. Does anyone know why?

Upvotes: 0

Views: 386

Answers (2)

r3plica
r3plica

Reputation: 13367

This was a weird one to solve. I had to change the way my function worked. I changed my function to this:

// Set our colours
self.setColour = function (propertyName, colour) {

    // Set the colour
    kit[propertyName] = colour.hex;

    // Store our model in the session
    configuratorService.saveToSession(kit);
};

and my HTML to this:

<div class="picker colour-picker">
    <ul class="picker-dropdown list-inline">
        <li ng-repeat="colour in teamController.colours" ng-class="{ 'active': controller.kit['colour' + ($index + 1)] === colour.hex }">
            <a href style="background-color: #{{ colour.hex }};" ng-click="teamController.setColour('colour' + ($parent.$index + 1), colour)"></a>
        </li>
    </ul>
</div>

For some reason I found that if I tried to pass the actual property, although it updated the property it did not update all references (as if dynamic properties in views are always treated as copies). Doing it this new way fixed the problem.

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

You need to wrap $index + 1 inside round brackets to evaluate it first before concatenating the string.

Additionally You need to use $parent notation while you wanted to access the $index of parent ng-repeat

ng-click="teamController.setColour(controller.kit['colour' + ($parent.$index + 1)], colour)"

Upvotes: 1

Related Questions