2015-12-18 7 views
1

Пожалуйста, обратите внимание на это tryout on Plunkr.Вызов Директивы другой директивы

У меня есть простой набор до:

<body ng-app="myApp"> 
    <div ng-controller="myController"> 
     <parent-directive></parent-directive> 
     <child-directive></child-directive> 
    </div> 
</body> 

С родительской директивы определяется как:

app.directive("parentDirective", [ 
    "$compile", 
    function (
     $compile) { 
     return { 
      scope: { 
       person: "=" 
      }, 
      restrict: "E", 
      template: "<h3>I'm a parent</h3>", 
      controller: [ 
       "$scope", 
       function ($scope) { 
        // --- PRIVATE --- // 

        var self = {}; 

        $scope.ClickMe = function() { 
         alert('Parent clicked'); 
        }; 
       }], 
      link: function ($scope, $elem, $attrs) { 
      } 
     }; 
    }]); 

И ребенок директива определяется как:

app.directive("childDirective", [ 
    "$compile", 
    function (
     $compile) { 
     return { 
      scope: { 
       person: "=" 
      }, 
      restrict: "E", 
      require: "^?parentDirective", 
      template: "<h3>I'm a child, click <button ng-click='ClickMe()'>here</button></h3>", 
      controller: [ 
       "$scope", 
       function ($scope) { 
        // --- PRIVATE --- // 

        var self = {}; 

        $scope.ClickMe = function() { 
         alert('child clicked'); 
         $scope.parentDirective.ClickMe(); 
        }; 
       }], 
      link: function ($scope, $elem, $attrs) { 
      } 
     }; 
    }]); 

child нажмите обрабатывается , но щелчок, определенный на `parent ', возвращает undefined:

TypeError: Cannot read property 'ClickMe' of undefined

глядя на консоль.

Любая идея, что происходит не так?

+0

Привет @Spikee вы должны проверить ссылку http://www.undefinednull.com/2014/07/07/Практическое руководство-pre-link-and-controller-methods-of-angle-directives/ – katmanco

ответ

0

Поместите свою дочернюю директиву в шаблон родительской директивы. Затем используйте $ scope. $ Parent.ClickMe(). Вот как это будет выглядеть.

Простая установка:

<body ng-app="myApp"> 
    <div ng-controller="myController"> 
     <parent-directive></parent-directive> 
    </div> 
</body> 

Родитель директива:

app.directive("parentDirective", [ 
    function() { 
     return { 
      scope: {}, 
      restrict: "E", 
      template: "<h3>I'm a parent</h3><child-directive></child-directive>", 
      controller: [ 
       "$scope", 
       function ($scope) { 
        $scope.ClickMe = function() { 
         alert('Parent clicked'); 
        }; 
       } 
      ] 
     }; 
    } 
]); 

Ребенок директива:

app.directive("childDirective", [ 
    function() { 
     return { 
      restrict: "E", 
      template: "<h3>I'm a child, click <button ng-click='ClickMe()'>here</button></h3>", 
      controller: [ 
       "$scope", 
       function ($scope) { 
        $scope.ClickMe = function() { 
         alert('child clicked'); 
         $scope.$parent.ClickMe(); 
        }; 
       } 
      ] 
     }; 
    } 
]); 
1

Any idea what's going wrong?

  1. Вы не можетrequire директива для братьев и сестер.
  2. Необходимые методы управления директивами dont подвергаются автоматическому воздействию на ваш объем.
  3. Вы должны разоблачить методы на самом контроллере, а не на назначенном $scope.

Вы можете require директива, которая определяется на тот же элемент как требующая директива, или на родительский элемент.

<child-directive parent-directive></child-directive> 

<parent-directive> 
    <child-directive></child-directive> 
</parent-directive> 

Когда вы require контроллер (он же. Подвергается API) другой директивы, это не волшебно в конечном итоге на $ объеме требующей директивы.

Однако в конечном итоге ваша функция link является четвертым аргументом.

Как так:

.directive('child', function() { 
    return { 
    require: '?^parentDirective', 
    link: function (scope, el, attrs, parentDirectiveController) { 
     scope.clickMe = function() { 
     parentDirectiveController.clickMe(); 
     }; 
    } 
    }; 
}); 

Expose методы, которые доступны в других директивах на this вместо $ сферы, как $ области видимости способ сделать это не будет работать так, как вы собираетесь его когда у вас выделены области.

.directive('parent', 
    controller: function() { 
    this.clickMe = function() {}; 
    } 
} 

Чтобы получить пример работает;

<parent> 
    <child></child> 
</parent> 

.directive('parent', function() { 
    return { 
    controller: function() { 
     this.clickMe = function() {}; 
    } 
    }; 
} 

.directive('child', function() { 
    return { 
    require: '^?parent', 
    link: function (scope, el, attrs, parentCtrl) { 
     scope.clickMe = function() { 
     parentCtrl.clickMe(); 
     }; 
    }  
    }; 
}); 

Упрощенный (& работает) версия вашего plunker: http://plnkr.co/edit/nao4EvbptQm7gDKkmZS2?p=preview

+0

Это отличный ответ и относится к вопросу. – Harbinger

0

Я мог бы думать о вашей проблеме немного по-другому, но я хотел бы взглянуть на $ трансляции , Идея заключается в том, что вы можете транслировать событие и иметь «n» количество директив в вашем случае, слушая это событие.

http://plnkr.co/edit/wBmX2TvC3yMXwItfxkgl

brodcast:

$scope.ClickMe = function() { 
        alert('child clicked'); 
        $rootScope.$broadcast('child-click');; 
       }; 

слушать:

$scope.$on('child-click', function (event, args) { 
        alert('Parent clicked'); 
       });