如何在变量更改后重新呈现指令?

时间:2015-12-23 16:16:11

标签: javascript angularjs

我正在使用星级评级指令。但是在从HTTP加载数据之前加载模板。所以我想在HTTP请求成功后重新加载指令模板。

HTML

var app = angular.module('myapp', []);
app.controller("movieCtrl", function($scope, $http) {

  $scope.starRating = 0;
  $scope.hoverRating = 0;


  $scope.mouseHover = function(param) {
    $scope.hoverRating1 = param;
  };

  $scope.mouseLeave = function(param) {

    $scope.hoverRating1 = param + '*';
  };
  //problem here
  //actual data coming via http
  //when value is changed i want to re-render below directive template
  setTimeout(function() {
    $scope.starRating = 5
  }, 1000);
});
app.directive('starRating', function() {
  return {
    scope: {
      rating: '=',
      maxRating: '@',
      readOnly: '@',
      click: "&",
      mouseHover: "&",
      mouseLeave: "&"
    },
    restrict: 'EA',
    template: "<div style='display: inline-block; margin: 0px; padding: 0px; cursor:pointer;' ng-repeat='idx in maxRatings track by $index'> \
                    <img ng-src='{{((hoverValue + _rating) <= $index) && \"http://www.codeproject.com/script/ratings/images/star-empty-lg.png\" || \"http://www.codeproject.com/script/ratings/images/star-fill-lg.png\"}}' \
                    ng-Click='isolatedClick($index + 1)' \
                    ng-mouseenter='isolatedMouseHover($index + 1)' \
                    ng-mouseleave='isolatedMouseLeave($index + 1)'></img> \
            </div>",
    compile: function(element, attrs) {
      if (!attrs.maxRating || (Number(attrs.maxRating) <= 0)) {
        attrs.maxRating = '5';
      };
    },
    controller: function($scope, $element, $attrs) {
      $scope.maxRatings = [];

      for (var i = 1; i <= $scope.maxRating; i++) {
        $scope.maxRatings.push({});
      };

      $scope._rating = $scope.rating;

      $scope.isolatedClick = function(param) {
        if ($scope.readOnly == 'true') return;

        $scope.rating = $scope._rating = param;
        $scope.hoverValue = 0;
        $scope.click({
          param: param
        });
      };

      $scope.isolatedMouseHover = function(param) {
        if ($scope.readOnly == 'true') return;

        $scope._rating = 0;
        $scope.hoverValue = param;
        $scope.mouseHover({
          param: param
        });
      };

      $scope.isolatedMouseLeave = function(param) {
        if ($scope.readOnly == 'true') return;

        $scope._rating = $scope.rating;
        $scope.hoverValue = 0;
        $scope.mouseLeave({
          param: param
        });
      };
    }
  };
});

JS

Ad Group
Annuity Calculator
Tax Deferred Annuity
Annuity Tables
annuities calculator
annuity formula
Annuities Explained
Deferred Annuies Calculator
Current Annuity Rates
Forbes.com
Annuity Definition
fixed income
Immediate fixed Annuities
Deferred Variable Annuities
401k Rollover
Deferred Annuity Rates
Deferred Annuities
Immediate Annuities Definition
Immediate Variable Annuities
Variable Annuity
Aig Annuities
Retirement Income
retirment system
Online Financial Planner
Certified Financial Planner

有关详细信息,请参阅Codepen

2 个答案:

答案 0 :(得分:5)

这是一个使用星号的简单评级指令,请注意逻辑位于link函数中,而不是控制器。

function starRating() {
  return {
    restrict: 'EA',
    template:
      '<ul class="star-rating" ng-class="{readonly: readonly}">' +
         // see ng-repeat here? this will update when scope.stars is updated
      '  <li ng-repeat="star in stars" class="star" ng-class="{filled: star.filled}" ng-click="toggle($index)">' +
      '    <i class="fa fa-star"></i>' + // or &#9733
      '  </li>' +
      '</ul>',
    scope: {
      ratingValue: '=ngModel',
      max: '=?', // optional (default is 5)
      onRatingSelect: '&?', // callback
      readonly: '=?' // set whether this should be changeable or not
    },
    link: function(scope, element, attributes) {
      if (scope.max == undefined) {
        scope.max = 5;
      }
      function updateStars() { // update to rating value
        scope.stars = [];
        for (var i = 0; i < scope.max; i++) {
          scope.stars.push({
            filled: i < scope.ratingValue
          });
        }
      };
      scope.toggle = function(index) {
        if (scope.readonly == undefined || scope.readonly === false){
          scope.ratingValue = index + 1;
          scope.onRatingSelect({
            rating: index + 1
          });
        }
      };
      scope.$watch('ratingValue', function(oldValue, newValue) {
        if (newValue) {
          updateStars();
        }
      });
    }
  };
}

答案 1 :(得分:1)

setTimeout函数上使用$ scope。$ apply(),您的代码将正常运行

我也对你的代码进行了简单的修改.. check here

  • 我创建了一个共享数据b / n控制器的服务
  • 添加了一些$ watch函数来检测值更改

var app = angular.module('myapp', []);
app.controller("movieCtrl", function($scope, $http, share) {

  $scope.starRating = 0;
  $scope.hoverRating = 0;

  $scope.mouseHover = function(param) {
    $scope.hoverRating1 = param;
  };

  $scope.mouseLeave = function(param) {
    $scope.hoverRating1 = param + '*';
  };
  $scope.$watch('starRating', function() {
    share.rating = $scope.starRating
  });
  setTimeout(function() {
    console.log('timeout set');
    $scope.starRating = 5;
    $scope.$apply();
  }, 1000);
});
app.factory('share', function() {
  var obj = {
    rating: 0
  }
  return obj;
});
app.directive('starRating', function() {
  return {
    scope: {
      rating: '=',
      maxRating: '@',
      readOnly: '@',
      click: "&",
      mouseHover: "&",
      mouseLeave: "&"
    },
    restrict: 'EA',
    templateUrl: "star1.html",
    compile: function(element, attrs) {
      if (!attrs.maxRating || (Number(attrs.maxRating) <= 0)) {
        attrs.maxRating = '5';
      };
    },
    controller: function($scope, $element, $attrs, share) {
      $scope.maxRatings = [];
      $scope.rating = share.rating;
      $scope.$watch('rating', function() {
        $scope._rating = share.rating;
      });
      for (var i = 1; i <= $scope.maxRating; i++) {
        $scope.maxRatings.push({});
      };

      $scope._rating = share.rating;

      $scope.isolatedClick = function(param) {
        if ($scope.readOnly == 'true') return;

        $scope.rating = $scope._rating = param;
        $scope.hoverValue = 0;
        $scope.click({
          param: param
        });
      };

      $scope.isolatedMouseHover = function(param) {
        if ($scope.readOnly == 'true') return;

        $scope._rating = 0;
        $scope.hoverValue = param;
        $scope.mouseHover({
          param: param
        });
      };

      $scope.isolatedMouseLeave = function(param) {
        if ($scope.readOnly == 'true') return;

        $scope._rating = $scope.rating;
        $scope.hoverValue = 0;
        $scope.mouseLeave({
          param: param
        });
      };
    }
  };
});