Как компонент angularjs может определить, что данные загружены в родительский контроллер?

У меня есть MainController с псевдонимом vm, у которого есть свойство vm.data, которое загружается из некоторого DataService.

Представление контроллера имеет настраиваемый компонент rs-dropdown, который должен загружать значения раскрывающегося списка после загрузки vm.data. vm.data является свойством главного контроллера.

Есть ли способ, как сам компонент может отслеживать изменения в родительском MainController и после загрузки данных выполнять действие загрузки?

Спасибо

ОБНОВЛЕНИЕ: Спасибо, Clavies, добавление ng-if="condition" к компоненту фактически приводит к тому, что этот компонент создается и инициализируется, когда условие истинно. Похоже, angular постоянно отслеживает ng-if и включает компонент при выполнении условия.

Здесь я добавил атрибут ng-if="vm.woReAssign" к моему компоненту, и теперь компонент инициализируется и создается только тогда, когда это условие истинно.

<rs-dropdown ng-if="vm.woReAssign"
                rs-server-controller="WorkOrder"
                rs-server-action="GetServiceProviderDropDownList"
                rs-filter="{woNum:'{{vm.woReAssign.WorkOrderNumber}}'}"
                rs-class="form-control">
</rs-dropdown>

P.S. Несмотря на то, что условие становится истинным через асинхронные вызовы с возможной задержкой, кажется, что Angular постоянно проверяет это условие, а затем оживляет компонент.


person monstro    schedule 18.11.2016    source источник
comment
чем это отличается от вопроса, который вы задали вчера? кроме того факта, что вы предоставляете здесь меньше информации, чем в предыдущем вопросе, когда в нескольких комментариях говорилось, что мы хотели бы видеть больше информации (и кода), чтобы понять, что вы действительно пытаетесь выполнить здесь?   -  person Claies    schedule 18.11.2016
comment
как я пытался объяснить вчера по этому вопросу, если поведение элемента связано с поведением родителя, то это не хороший кандидат на роль компонента и, вероятно, вместо этого должна быть директива.   -  person Claies    schedule 18.11.2016
comment
Что может быть проще? Может ли компонент отслеживать изменение какого-либо свойства контроллера, зачем вам код?   -  person monstro    schedule 18.11.2016
comment
Я не уверен, как это можно объяснить по-другому. Компоненты являются автономными. Они изолированы. Они не предназначены для взаимодействия с другими элементами на странице, за исключением случаев, когда им явно передаются данные. Что касается просмотра кода, это стандарт для вопросов здесь; Наблюдение за написанным вами кодом дает нам возможность увидеть ваш подход к проблеме, а не строить догадки, и дает некоторую информацию для тестирования и устранения неполадок.   -  person Claies    schedule 18.11.2016
comment
так что я думаю, если вы предполагаете, что ваш вопрос прост, и вы хотите получить простой ответ, они не могут, по крайней мере, не так, как вы надеетесь. Если вы готовы предоставить некоторый минимально воспроизводимый пример проблемы, мы можем найти способ получить ваш желаемое поведение.   -  person Claies    schedule 18.11.2016
comment
например, если ваш компонент принимает данные, которые контроллер извлекает в качестве параметра, вы можете использовать ng-if, чтобы не отображать компонент, пока данные не будут готовы для передачи ему. Существуют и другие методы, которые также можно использовать, но ответственность, вероятно, лежит на родительском элементе, а не на дочернем компоненте.   -  person Claies    schedule 18.11.2016
comment
Идеальный !! Отметьте это как ответ.   -  person monstro    schedule 18.11.2016


Ответы (1)


Я попытался создать сценарий, который вы упомянули. Вы можете прослушивать обновление контроллера через жизненный цикл крючок жизненного цикла $onchange в дизайне компонента.

См. пример, где раскрывающийся компонент заполняется, когда данные заполняются в родительский контроллер при нажатии кнопки .Надеюсь это поможет!

var app = angular.module("myApp", []);

app.controller("mainController", function(bookService, $scope) {
  var vm = this;
  vm.showDropdown = false;
  vm.loadBooks = function() {
    bookService.getAllBooks().then(function(books) {
      vm.books = books;
      vm.showDropdown = true;
    }, function(err) {
      vm.showDropdown = false;
      //error
    });
  }
});

function dropdownControllerFn(bookService) {
  var model = this;
  model.$onInit = function() {
    //do intialization
  }

  model.$onChanges = function(changes) {
    model.books = changes;
  };
}

app.component("rsDropdown", {
  templateUrl: 'dropdownComponent.html',
  bindings: {
    books: '<'
  },
  controllerAs: 'model',
  controller: dropdownControllerFn
});

app.factory('bookService', ['$http', '$timeout', '$q', function($http, $timeout, $q) {
  var urlBase = 'favouriteBooks.json';
  var service = {};
  service.getAllBooks = function() {
    return $http.get(urlBase).then(function(response) {
      return response.data;
    });
  };
  return service;
}]);;
}]);

выпадающий компонент.html

<div>
   <select ng-options="s.bookName for s in model.books" ng-model="selitem">
      <option value="">--Select--</option>
    </select>
</div>

index.html

<body data-ng-app="myApp" data-ng-controller="mainController as vm">
  <rs-dropdown books=vm.books ng-if="vm.showDropdown"></rs-dropdown>
  <button ng-click="vm.loadBooks()">Get Books</button>
</body>
person Sumit Deshpande    schedule 18.11.2016