2

Trying to make a rating directive but I'm stuck at getting rating2 to work. The first rating worked because the rating1 is hardcoded within the controller. But normally I have to get the saved rating from the db, which I'm trying to do with rating2, as u can see the value is fetched but the directive is not appearing.

https://codepen.io/eldyvoon/pen/MbBNLP

  <div star-rating ng-model="rating.rating1" max="10" on-rating-select="rating.rateFunction(rating)"></div>

  <br>but rating2 is actually there:
    {{rating.rating2}}

  <star-rating ng-model="rating.rating2" readonly="rating.isReadonly"></star-rating>

Need expert of directive to help.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Jenny Mok
  • 2,744
  • 9
  • 27
  • 58

4 Answers4

0

Initiate rating2 :

function RatingController($http) {
    this.rating1 = 5;
    this.rating2 = 0; //ADD THIS LINE
  var self = this;

it works for me

check here

  • LOL try to understand the problem dude. – Jenny Mok Dec 11 '16 at 14:07
  • Of course it worked for u coz you don't get the question. – Jenny Mok Dec 11 '16 at 14:10
  • dude, the problem that you are using the instance (self) that don't contain (rating2) simply. thats why you can't see your rating2. – Aymen Dhaya Dec 11 '16 at 14:11
  • someone give this guy a downvote and explain to him what's wrong with his answer. – Jenny Mok Dec 11 '16 at 14:12
  • after self.rating2 = res.data.rating2; try to check both values of (this.rating2) and (self.rating2); you will see the difference. self contain 5 but this is NADA. your div use RatingController and not an instance of RatingController inside of RatingController. :) – Aymen Dhaya Dec 11 '16 at 14:16
  • what has this and self has to do with $http? please try to understand I have to use $http, read the question carefully :) – Jenny Mok Dec 11 '16 at 14:36
  • Please try not to insult people who are trying to help. – Anirudh Mangalvedhekar Dec 11 '16 at 15:00
  • Strange reaction from someone who ask for help, note that Horst Jahns gave you the same solution that i suggest. just try to be more flexible. Good luck anyway :) – Aymen Dhaya Dec 11 '16 at 15:54
0

First of all, I'm not a directive expert but i'm trying to help. I think that when html is first load, the values from db not finish execute and bind into html. The best way is not using directive instead using controller to fetch data from db.

digit
  • 4,479
  • 3
  • 24
  • 43
0

You pass a model without rating2 into your directive and the changes from the parent controller won't affect it, because variable is created afterwards. Adding a watcher in your linker on parent scope will solve the problem;

scope.$parent.$watch('', function(rating){
  updateStars();
});

Other solution would be to define a starting value in your controller.

this.rating2 = 1;

Notice that it is bad design to have a scope variable for each rating. It is cleaner to have an array of ratings and you actually do not need the watcher by doing so.

https://codepen.io/hoschnok/pen/LbJPqL

angular controller

function RatingController($http) {
    this.ratings = [4];
    var self = this;
    $http.get('https://api.myjson.com/bins/o0r69').then(function(res){
        self.ratings.push(res.data.rating2);
    });
}

HTML

<div ng-app="app" ng-controller="RatingController as rating" class="container">
    <div ng-repeat="r in rating.ratings">
        <div star-rating ng-model="r" max="10" on-rating-select="rating.rateFunction(rating)"></div>
    </div>
</div>
oshell
  • 8,923
  • 1
  • 29
  • 47
  • I found a trick. use ng-if, it solved the problem :D http://stackoverflow.com/a/28766260/7095330 – Jenny Mok Dec 11 '16 at 15:28
  • 1
    It is just another solution. you could also use ui router to resolve the value before you pass it which is cleaner solution. Tried to explain you why this happens. – oshell Dec 11 '16 at 15:36
0

The watcher change handler function has parameters reversed:

    //INCORRECT parameters
    //scope.$watch('ratingValue', function(oldValue, newValue) {
    //CORRECT parameters
    scope.$watch('ratingValue', function(newValue, oldValue) {
      if (newValue) {
        updateStars();
      }
    });

The first argument of the listening function should be newValue.

The DEMO on CodePen


ALSO

The ng- prefix is reserved for core directives. See AngularJS Wiki -- Best Practices

JS

  scope: {
    //Avoid using ng- prefix
    //ratingValue: '=ngModel',
    ratingValue: '=myModel',
    max: '=?', // optional (default is 5)
    onRatingSelect: '&?',
    readonly: '=?'
  },

HTML

 <!-- AVOID using the ng- prefix 
 <star-rating ng-if='rating' ng-model="rating.rating2"
       max="10" on-rating-select="rating.rateFunction(rating)">
 </star-rating>
 -->

 <!-- INSTEAD -->
 <star-rating ng-if='rating' my-model="rating.rating2"
       max="10" on-rating-select="rating.rateFunction(rating)">
 </star-rating>

When a custom directve uses the name ng-model for an attribute, the AngularJS framework instantiates an ngModelController. If the directive doesn't use the services of that controller, it is best not to instantiate it.

georgeawg
  • 48,608
  • 13
  • 72
  • 95