0

У меня есть директива, которая содержит дочернюю директиву, которая также содержит дочернюю директиву, и я пытаюсь использовать контроллер верхнего уровня для доступа к контроллеру внука и вызывать функцию, которая является частью контроллер внуков. Я получаю сообщение об ошибке, когда функция не определена. Я хотел бы иметь возможность контролировать директиву внука, используя самый верхний родительский элемент через контроллера внуков.angularjs несколько вложенных родительских дочерних директив связи

angular.module('components', []) 
 
.controller('MyButtonController', ['$scope', function($scope){ 
 
    this.mySubButtons = []; 
 
    
 
    this.addSubButtons = function(s){ 
 
     this.mySubButtons.push(s); 
 
    } 
 
    
 
}]).controller('MyButtonGroupController', ['$scope', function($scope){ 
 
    this.myButtons = []; 
 
    this.addMyButtonCtrl = function(ctrl){ 
 
     this.myButtons.push(ctrl); 
 
    }; 
 
    this.setName = function(name){ 
 
     //undefined function 
 
     this.myButtons[0].setName(name); 
 
     console.log(this.myButtons); 
 
    } 
 
}]) 
 
.directive('mySubButton', function(){ 
 
    return { 
 
     restrict: 'E', 
 
     scope:{}, 
 
     require: ['^myButton', 'mySubButton'], 
 
     template: '<div>Hello {{name}}</div>', 
 
     controller: ['$scope', function($scope){ 
 
      $scope.name="phil"; 
 
      this.setName = function(name){ 
 
       $scope.name = name; 
 
      } 
 
     }], 
 
     link: function(scope,element,attrs, ctrls){ 
 
      ctrls[0].addSubButtons(ctrls[1]); 
 
     } 
 
    } 
 
}) 
 
.directive('myButton', function() { 
 
     return { 
 
      restrict: 'E', 
 
      scope:{}, 
 
      require: ['^myButtonGroup','myButton'], 
 
      controller: 'MyButtonController', 
 
      template: '<div><my-sub-button></my-sub-button><my-sub-button></my-sub-button></div>', 
 
      link: function(scope,element,attrs, ctrls){ 
 
       ctrls[0].addMyButtonCtrl(ctrls[1]); 
 
      } 
 
     } 
 
    }) 
 
.directive('myButtonGroup', function(){ 
 
    return { 
 
     restrict:'E', 
 
     scope:{}, 
 
     transclude: true, 
 
     replace: true, 
 
     controller: 'MyButtonGroupController', 
 
     template: '<div ng-transclude></div>', 
 
     link: function(scope,element, attrs, groupCtrl){ 
 
      var myButtonsCtrls = groupCtrl.myButtons; 
 
      groupCtrl.setName('Jill'); 
 
      
 
     } 
 
    } 
 
}) 
 

 
angular.module('HelloApp', ['components'])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script> 
 
<body ng-app="HelloApp"> 
 
    <my-button-group> 
 
     <my-button></my-button> 
 
     <my-button></my-button> 
 
    </my-button-group> 
 
</body>

jsfiddle ссылка: http://jsfiddle.net/jaLhwgbg/2/

ответ

0

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

So MyButtonController будет $scope.$broadcast('doSomethingMyButtonChildren'), и ваша директива mySubButton будет действовать так, как это scope.$on('doSomethingMyButtonChilden', function() {}).

Вышеупомянутая информация является лучшей практикой для более чистого, более читаемого, более легко проверяемого кода. Однако, чтобы ответить на вопрос о происхождении, ваша функция addMyButtonCtrl имеет проблему контекста.

Неправильный

this.mySubButtons = []; 
this.addMyButtonCtrl = function(ctrl){ 
    this.mySubButtons.push(ctrl); 
    // 'this' is refering to the closure of the function addMyButtonCtrl 
    // not of the controller itself 
}; 

Правильная

this.mySubButtons = []; 
this.addMyButtonCtrl = function(ctrl){ 
    mySubButtons.push(ctrl); 
}; 
+0

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

0

Вы не определили SetName в MyButtonController, что тот тип, который вы пытаетесь вызвать SetName на.

http://jsfiddle.net/y2vfhzwe/

MyButtonController становится:

.controller('MyButtonController', ['$scope', function($scope){ 
    this.mySubButtons = []; 

    this.addSubButtons = function(s){ 
     this.mySubButtons.push(s); 
    } 
    this.setName = function(name) { 
     this.mySubButtons[0].name = name; 
    } 
Смежные вопросы