@Lodin

Почему происходит двойное присвоение внешней переменной в директиве Angular?

Пишу приложение на AngularJS с компонентным подходом, где одна директива инициализирует другую и передаёт ей некие данные. Однако при передаче данных присвоение происходит дважды (что ведёт также к проблемам с two-way binding).

Вот код:

Инициализация модуля
angular.module('myModule', []);

Родительская директива
var ParentController = (() => {
  function ParentController() {
    this._increasableValue = 1;
  }

  ParentController.prototype.update = function() {
    this._increasableValue += 1;
  }

  Object.defineProperty(ParentController.prototype, "increasableValue", {
    get: function() {
      return this._increasableValue;
    },
    enumerable: true,
    configurable: true
  });

  return ParentController;
})()

angular
  .module('myModule')
  .controller('parentController', ParentController)
  .directive('parentDirective', () => {
    return {
      restrict: 'E',
      scope: {},
      controller: 'parentController',
      controllerAs: 'ctrl',
      template: `
<div class="container">
        <child-directive inc="{{ctrl.increasableValue}}"></child-directive>
</div>
<button ng-click="ctrl.update()">Update</button>`
    }
  });


Дочерняя директива
var ChildController = (() => {
  function ChildController() {}

  Object.defineProperty(ChildController.prototype, "increasableValue", {
    get: function() {
      return this._increasableValue;
    },
    set: function(value) {
      this._increasableValue = value;
      console.log(this._increasableValue); // выводит дважды
    },
    enumerable: true,
    configurable: true
  });

  return ChildController;
})();

angular
  .module('myModule')
  .controller('childController', ChildController)
  .directive('childDirective', () => {
    return {
      restrict: 'E',
      scope: {
        increasableValue: '@inc'
      },
      bindToController: true,
      controller: 'childController',
      controllerAs: 'ctrl',
      template: `
<div class="container">
    <div>{{ctrl.increasableValue}}</div>
</div>`
    }
  });


Бутстраппинг
angular.bootstrap(document.getElementById('wrapper'), ['myModule'])


index.html (частично)
<div id="wrapper">
  <parent-directive>Loading...</parent-directive>
</div>


Почему происходит это задвоение, и что с ним можно сделать?

Рабочий пример на jsfiddle
  • Вопрос задан
  • 228 просмотров
Пригласить эксперта
Ответы на вопрос 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
потому что вы используете геттеры и сеттеры, там есть свои нюансы.

Ну и да, если мы включим двустороннее связывание внутри дочерней директивы (дочерняя тут не очень подходит, наши компоненты должны быть по возможности независимыми), то установка значения будет происходить только один раз, в момент биндинга значения на контроллер.

Лично я для упрощения пробрасываю внутрь кусочек объекта, и просто никогда не меняю его в компоненте, а прошу это сделать сервисы. Тогда те смогут пробросить состояние по кругу.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы