наблюдение запускается на контроллере, но не директива

#angularjs

#angularjs

Вопрос:

У меня есть директива, которая отслеживает привязку, и, как ни странно, это наблюдение отключается, если переменная изменяется сразу, но если оно ожидает возврата http-вызова, тогда оно не запустит наблюдение. Странно то, что он отлично запускает просмотр контроллеров, но не директивный, хотя они, по сути, находятся на одном и том же.

Вот несколько фрагментов кода, описывающих проблему. Директива:

 .directive('afcAutocomplete', function() {
return {
  restrict: 'AEC',
  scope: {
      binding: '=ngModel',
      source: '=',
      filter: '=?',
      [...]
  },
  templateUrl: '/afc_template/afc-autocomplete.html',
  controller: function($scope, $element, $attrs, $compile, $timeout) {
      [...]
      $scope.$watch('binding', function(newValue) {
          console.log('new val: ', newValue);
          setDisplayBinding(newValue);
      });
[...]
  

корневой контроллер:

 app.controller("editController", function($scope, $http, $routeParams) {
  if($routeParams.id)
    qDocument = editFormUtility.load($routeParams.id, $routeParams.document_type); //returns a $http call to an API
  else {
    qDocument = { 
      header: {
        id: guid(),
        schema   : $routeParams.document_type,
        languages: ["en"]
      },  
      government: $scope.userGovernment() ? { identifier: $scope.userGovernment() } : undefined,
    };
[...]
  

контроллер:

 app.controller("editMeasure", function ($scope) {
  $controller('editController', {$scope: $scope});

  $scope.$watch('document.government', function() {
    if($scope.document)
      console.log('government changed: ', $scope.document.government);
  });
[...]
  

Шаблон editMeasure:

 <div afc-autocomplete ng-model="document.government" source="ac_countries" filter="genericFilter"></div>
  

Что меня сбивает с толку, так это то, что если я запускаю новый документ, то просмотр работает, но если я редактирую документ, и он проходит через вызов $ http, тогда просмотр контроллера все еще работает, но просмотр директивы не работает. Что касается журналов консоли, я вижу «document: «, затем «правительство изменено» в качестве последнего сообщения, поэтому после журнала «document:» нет сообщения «new val:», которое является показателем того, что мы изменили документ.
Еще одно замечание. Документ изначально не определен, затем становится объектом с ‘government’, установленным для другого объекта, что-то вроде {id: ‘ca’}.

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

1. Попробуйте воссоздать в jsfiddle. net или plnkr.co

2. Можете ли вы убедиться, что, когда $watch применяется в контроллере вашей директивы, binding определено? Потому что, если это не определено в результате того, что document в вашем контроллере не определено, будет проблемой, и $watch не будет работать.

3. Чувак, ты потрясающий! Я первым делом установил $scope.document в {} в контроллере, и теперь это работает!

Ответ №1:

Спасибо Вайдику за то, что помог мне найти ответ.

Проблема в том, что если watch создается для привязки, которая в данный момент не определена, то, когда вы ее установите, она не будет работать. Поэтому вам нужно убедиться, что привязка установлена на что-нибудь, на что угодно.

В моем случае я установил $scope.document = {} , и тогда привязка сработала.

Angular — странный зверь. Кто-нибудь может объяснить в комментариях, почему установка $ scope.document = {} позволяет моему просмотру для $ scope.document.government внезапно сработать, хотя в конечном итоге я полностью заменяю объект, назначенный $ scope.document (я даю ему совершенно новый объект, я не просто устанавливаю свойства)? Я в замешательстве, потому что вы не смогли бы сделать это с обычными ссылками, потому что я устанавливаю новую ссылку для $ scope.document , поэтому Angular делает что-то еще волшебное, и я чувствую, что знание того, что он делает, может помочь мне устранить будущие проблемы.