DevStarlight DevStarlight - 5 months ago 14
AngularJS Question

directive that controlls upvotes and downvotes

I'm developing a upvote/downvote controlling system for a dynamic bunch of cards.

I can controll if I click to the img the

checked = true
and
checked = false
value but The problem I've found and because my code doesn't work as expected is I can't update my value in the
ng-model
, so the next time the function is called I receive the same value. As well, I can't update and show correctly the new value. As well, the only card that works is the first one (it's not dynamic)

All in which I've been working can be found in this plunk.

As a very new angular guy, I tried to investigate and read as much as possible but I'm not even 100% sure this is the right way, so I'm totally open for other ways of doing this, attending to performance and clean code. Here bellow I paste what I've actually achieved:

index.html

<card-interactions class="card-element" ng-repeat="element in myIndex.feed">
<label class="rating-upvote">
<input type="checkbox" ng-click="rate('upvote', u[element.id])" ng-true-value="1" ng-false-value="0" ng-model="u[element.id]" ng-init="element.user_actions.voted === 'upvoted' ? u[element.id] = 1 : u[element.id] = 0" />
<ng-include src="'upvote.svg'"></ng-include>
{{ element.upvotes + u[1] }}
</label>
<label class="rating-downvote">
<input type="checkbox" ng-click="rate('downvote', d[element.id])" ng-model="d[element.id]" ng-true-value="1" ng-false-value="0" ng-init="element.user_actions.voted === 'downvoted' ? d[element.id] = 1 : d[element.id] = 0" />
<ng-include src="'downvote.svg'"></ng-include>
{{ element.downvotes + d[1] }}
</label>
<hr>
</card-interactions>


index.js

'use strict';

var index = angular.module('app.index', ['index.factory']);

index.controller('indexController', ['indexFactory', function (indexFactory) {

var data = this;

data.functions = {
getFeed: function () {
indexFactory.getJSON(function (response) {
data.feed = response.index;
});
}
};

this.functions.getFeed();
}

]);

index.directive('cardInteractions', [ function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
scope.rate = function(action, value) {
var check_up = element.find('input')[0];
var check_down = element.find('input')[1];
if (action === 'upvote') {
if (check_down.checked === true) {
check_down.checked = false;
}
} else {
if (action === 'downvote') {
if (check_up.checked === true) {
check_up.checked = false;
}
}
}
}
}
};
}]);


Hope you guys can help me with this.
Every contribution is appreciated.

Thanks in advice.

Answer

I have updated your directive in this plunker, https://plnkr.co/edit/HvcBv8XavnDZTlTeFntv?p=preview

index.directive('cardInteractions', [ function () {
  return {
    restrict: 'E',
    scope: {
      vote: '='
    },
    templateUrl: 'vote.html',
    link: function (scope, element, attrs) {

      scope.vote.upValue = scope.vote.downValue = 0;

      if(scope.vote.user_actions.voted) {
        switch(scope.vote.user_actions.voted) {
          case 'upvoted':
            scope.vote.upValue = 1;
            break;
          case 'downvoted':
            scope.vote.downValue = 1;
            break;
        }
      } 

      scope.upVote = function() {
        if(scope.vote.downValue === 1) {
          scope.vote.downValue = 0;
          scope.vote.downvotes--;
        }

        if(scope.vote.upValue === 1) {
          scope.vote.upvotes++;  
        } else {
          scope.vote.upvotes--;
        }
      };

      scope.downVote = function() {
        if(scope.vote.upValue === 1) {
          scope.vote.upValue = 0;
          scope.vote.upvotes--;
        }

        if(scope.vote.downValue === 1) {
          scope.vote.downvotes++;  
        } else {
          scope.vote.downvotes--;
        }
      };
    }
  };