PaulTMatik
@PaulTMatik

Как исправить ошибку рендера в angularjs при использовании директив?

Недавно начал изучать angularjs и возникла ситуация с рендером.
html
<radiogroup>
    <radio checked>Option 1</radio>
    <radio>Option 2</radio>
</radiogroup>


js
var application = angular.module('application', []);
application.directive('radiogroup', function(){
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    controller: function($scope, $element) {
      var radios = $scope.radios = [];

      this.check = function(radio) {
        angular.forEach(radios, function(radio) {
          radio.checked = false;
        });
        radio.checked = true;
      }

      this.addToGroup = function(radio, checked) {
        if (checked) this.check(radio);
        radios.push(radio);
      };
    },
    template: '<div class="radiogroup" ng-transclude></div>',
    replace: true
  }
})

.directive('radio', function() {
  return {
    require: '^radiogroup',
    restrict: 'E',
    transclude: true,
    scope: {},
    link: function(scope, element, attrs, radiogroupCtrl) {
      radiogroupCtrl.addToGroup(scope, angular.isUndefined(attrs.checked) ? false : true);
      element.bind('click', function(){
        radiogroupCtrl.check(scope);
      });
    },
    template: '<div class="radio"  ng-class="{active: checked}" ng-transclude></div>',
    replace: true
  }
});

При загрузке страницы, всё подменяется как надо (если элемент был помечен как checked, то заменяется на div с классом active), но если начать кликать по другому, то ничего не происходит, однако, если посмотреть на объекты в переменной radios, то там всё в порядке - параметр checked сменяется true/false как надо. Не могу ума дать, почему DOM не обновляется после клика по элементу?
  • Вопрос задан
  • 2401 просмотр
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Потому что не запускается цикл $digest. Почитайте что ли как работает data-binding в angularjs.

Если кратко - на каждое асинхронное изменение $scope нужно запускать $digest или $apply. Разница такая: $digest запускает обновление только текущего и дочерних скоупов. $apply обновляет все все все. посему в таких штуках лучше использовать $apply.

element.bind('click', function(){
        scope.$apply(function () {
           radiogroupCtrl.check(scope);
        });
});
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы