Двухсторонние привязки данных не запускают $ onChanges в компонентах

#angularjs #angularjs-components #angularjs-1.5

#angularjs #angularjs-компоненты #angularjs-1.5

Вопрос:

Двухсторонние привязки данных не обновляются между компонентами

Я настраиваю межкомпонентную связь, используя двустороннюю привязку данных. У меня есть один родительский контроллер, который извлекает данные из вызова AJAX и отправляет эти данные двум компонентам.

Я пытался изменить данные, которые передаются компонентам, но если дочерний компонент 1 обновляет данные, дочерний компонент не получает обновленные данные, хотя двусторонняя привязка данных присутствует. Я читал, что хук $ onChanges не будет фиксировать событие изменения для двухсторонней привязки данных.

 <div ng-controller="ParentController as ctrl">
    <child1 data="ctrl.data"></child1>
    <child2 data="ctrl.data"></child>
</div>
  

Родительский контроллер:

 var app = angular.module('app',[]);
app.controller('ParentController', function($scope, $get){
   //get data from AJAX call
   this.data = getDataFromAjaxCall();
}
  

Дочерний компонент 1:

 app.component('child1',{
   bindings : {
      data : '='
   },
   controller: function($scope){
      var self = this;
      self.$onChanges = function(changes){
         if(changes.data)
            console.log('data changed');
      }
      self.addData = function(){
         self.data.push({
            id : 10,
            name : 'abc'
         });
      }
   }
});
  

Дочерний компонент 2:

 app.component('child2',{
   bindings : {
      data : '='
   },
   controller: function($scope){
      var self = this;
      self.$onChanges = function(changes){
         if(changes.data)
            console.log('data changed');
      }
      self.addData = function(){
         self.data.push({
            id : 20,
            name : 'pqr'
         });
      }
   }
});
  

Я ожидаю получить обновленные данные в компоненте child1, если компонент child2 изменил данные, и наоборот.

Комментарии:

1. Функции, выполняющие XHRs, не могут возвращать данные. Они могут возвращать только обещания, из которых необходимо извлечь данные.

Ответ №1:

Перехват $onChanges жизненного цикла запускается только при изменениях односторонних ( "<" ) и атрибутивных ( "@" ) привязок. Это не запускает изменения в двухсторонних ( "=" ) привязках.

С компонентами используйте одностороннюю ( "<" ) привязку для входных данных и привязку выражения ( "amp;" ) для выходных данных:

 app.component('child1',{
   bindings: {
       ̶d̶a̶t̶a̶ ̶:̶ ̶'̶=̶'̶
       facts: "<",
       factsChange: "amp;", 
   },
   controller: function(){
      this.$onChanges = function(changes){
         if(changes.facts)
            console.log('facts changed');
      }
   }
});
  

Избегайте использования двухсторонних ( "=" ) привязок. Они усложняют переход на Angular 2 .

Для получения дополнительной информации см. Руководство разработчика AngularJS — Архитектура приложений на основе компонентов.

Также будьте осторожны с привязками, которые начинаются с data . Директивная нормализация удалит имена, начинающиеся с data- . Смотрите Руководство разработчика AngularJS — Нормализация директив.


Функции, выполняющие XHRs, не могут возвращать данные. Они могут возвращать только обещания, из которых необходимо извлечь данные.

 var app = angular.module('app',[]);
app.controller('ParentController', function($scope, $get){
   //get data from AJAX call
   ̶t̶h̶i̶s̶.̶d̶a̶t̶a̶ ̶=̶ ̶g̶e̶t̶D̶a̶t̶a̶F̶r̶o̶m̶A̶j̶a̶x̶C̶a̶l̶l̶(̶)̶;̶
   var promise = getDataFromAjaxCall();
   promise.then( response => {
       this.data = response.data;
   });
}
  

Браузеры JavaScript используют однопоточную неблокирующую архитектуру ввода-вывода, управляемую событиями. Программистам, знакомым с императивными стилями программирования, необходимо изменить представление об IO с помощью браузеров JavaScript.

Комментарии:

1. Что, если существует несколько компонентов, и каждый должен получать обновленные данные, если какой-либо из компонентов обновляет их?

2. Прочитайте Angular 2 Руководство разработчика — Синтаксис шаблона — Двусторонняя привязка . В руководстве показано, как Angular 2 выполняет двустороннюю привязку. Если компоненты AngularJS выполнены таким образом, переход на Angular 2 будет намного проще.