1

In my controller I have an array of objects (I'm just getting started, so forgive me if this is terribly naive or something):

$scope.links = [
    {
        'votes': 6,
        'voted_on': false
    },
    {
        'votes': 7,
        'voted_on': false
    }
];

I want to list these out in the view and modify some of the properties on click, maintaining some complex state reflecting the change in the DOM:

<ul>
    <li ng-repeat="link for links">
        <a ng-click="updateProperties()">Vote</a>
        {{link.votes}}
    </li>
</ul>

You know, I would like updateProperties() to manage a lot of stateful logic (change the color of the {{link.votes}}, increment link.votes, disallow incrementing if they have already voted, etc. ). I get that I need to define the function on $scope but I'm just not sure what that would look like, so help would be much appreciated. Thanks.

ZenLikeThat
  • 2,052
  • 3
  • 16
  • 23

2 Answers2

2

One way would be to have updateProperties to have a parameter that is a unique identifier for the poll in which the vote is related to. The logic of dealing with what the click does will reside inside updateProperties and that will be up to you to define as per what you want. The function is just a standard javascript function and can be defined inside your controller like

$scope.updateProperties = function(pollID){...} and as long as the controller that this resides in is active in the part of the page that you call it from then you can use the function.

Check out the Angular Docs, and their mockups on the main page (I think one that's on the main page might be of use to you).

ryaanwells
  • 280
  • 1
  • 2
  • 12
  • Hm, yeah, I think I will be taking that approach using a (key,value) sequence in the ng-repeat as mentioned here: http://stackoverflow.com/questions/10954286/angularjs-how-can-i-reference-the-property-name-within-an-ng-repeat I'm not sure if it's the most elegant way to do things, but it will get the job done until I know Angular a little bit better. Cheers! – ZenLikeThat Apr 12 '13 at 16:23
  • The (key,value) approach might do fine. I've always found it easier just getting the entire object and then accessing the attributes that I need. e.g. in your case `"link for links"` and `Vote {{link.votes}}` – ryaanwells Apr 12 '13 at 16:28
  • Hm, I'm a bit confused by this answer, as ideally that would be what I want- to update the state of the object I am currently "on" when the function is called by passing it into the function. Would I have to add a `pollID` attribute to each object, and how would I use that in that callback function? Would I have to loop through the array and find the object with the correct `pollID` ? – ZenLikeThat Apr 12 '13 at 19:06
  • 1
    For this approach to work you will need to be able to differentiate between polls and having some sort of `pollID` that is globally unique for all polls makes sense. have a look at this [http://plnkr.co/edit/j4ll1P](http://plnkr.co/edit/j4ll1P) – ryaanwells Apr 13 '13 at 10:37
  • Awesome. Thanks a lot ryaanwells! Truly going above and beyond the call of duty. – ZenLikeThat Apr 14 '13 at 19:05
0

An easier way is to use the $index to find the item, as an example

<ul>
<li ng-repeat="link for links">
    <a ng-click="toggleVotedOn($index)">Vote</a>
    {{link.votes}}
</li>

And in your controller,

$scope.toggleVotedOn = function(i) {
    $scope.links[i].voted_on = !($scope.links[i].voted_on);
}
Cagatay Kalan
  • 4,066
  • 1
  • 30
  • 23