2014-12-18 7 views
7

Как вызвать метод, определенный в дочерней директиве, в пределах кнопки щелчка при прослушивании родительской директивы.Вызов функции дочерней директивы из родительской директивы в AngularJs

angular.module('editableDivDirective', []) 

.directive("editableDiv", function() { 
    var directive = {}; 
    directive.restrict = 'E'; 
    directive.replace = 'true'; 
    directive.scope = {}; 
    directive.transclude = 'true'; 
    directive.template = 
     '<div id="wrapper">' + 
      '<div required class="text-area" name="search" contenteditable="true" ng-model="formData.text"></div>' + 
      '<button type="submit" class="btn btn-warning add-button" id="submit" ng-click="createTodo()">Add</button>' + 
     '</div>'; 
    directive.link = function(scope, element, attrs, controller) { 
     scope.createTodo = function(){ 
      // do something   
      // Call child directive setPlaceholderText() 
     } 
    }; 

    return directive; 
}) 
.directive("contenteditable", function() { 
    var directive = {}; 
    directive.require = ['^editableDiv','?ngModel']; 
    directive.restrict = 'A'; 
    directive.scope = {}; 
    directive.link = function(scope, element, attrs, ctrls) { 
     var ngModel = ctrls[1]; 
     var editableDivController = ctrls[0]; 

     function setPlaceholderText(){ 
      return element.html("Hello World"); 
     } 

    return directive; 
}) 

Я хочу вызвать директиву ребенок setPlaceholderText(), когда 'scope.createTodo()' родительско директива называется.

Как это можно сделать.

+0

Каков ваш конкретный прецедент? Что вы пробовали? – Patrick

+0

@Patrick Я добавил более подробную информацию. Извините, был вдали от моей системы, поэтому не мог добавить это вовремя. – jsbisht

ответ

3

В вашей родительской директивы

link: function($scope,$el,$attr) { 
    $el.find(".thing").on('click',function(event){ 
     $scope.$broadcast('thing', $scope.someData); 
    }); 
} 

В вашей директиве ребенка

link: function($scope. $el, $attr) { 
    $scope.$on('thing',function(event, someData) { 
     alert('My parent called me with this data: ' + someData); 
    }); 
} 
+1

Спасибо Мэтью. Будет ли это применяться, если директивы имеют изолированный охват? – jsbisht

2

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

Вот jsfiddle с примерами директивы $ broadcast to child и с использованием техники контроллера.

angular.module("myApp", []) 

.directive("parentDirective", function() { 
    var directive = {}; 
    directive.restrict = "E"; 
    directive.scope = {}; 
    directive.template = '<div>' + 
     '<button type="button" ng-click="broadcastDemo()">' + 
      'Broadcast to child' + 
     '</button>' + 
     '<button type="button" ng-click="controllerDemo()">' + 
      'Use Controller' + 
     '</button><br /><br />' + 
     '<child-directive></child-directive>'; 
    //Setup directive controller 
    directive.controller = function ($scope) { 
     var ctrl = this; 
     //Store events for convenience 
     var events = ctrl.events = { 
      setPlaceHolderText: "setPlaceHolderTextEvent" 
     }; 

     $scope.broadcastDemo = function() { 
      //$broadcast event and optional additional args 
      $scope.$broadcast(events.setPlaceHolderText, "Additional arg1", "Additional arg2"); 
     }; 

     $scope.controllerDemo = function() { 
      //do some work 

      //call the ctrl.setPlaceHolderText added by child 
      if (ctrl.setPlaceHolderText) { 
       ctrl.setPlaceHolderText(); 
      } 
     }; 
    }; 
    return directive; 
}) 

.directive("childDirective", function() { 
    var directive = {}; 
    directive.restrict = "E"; 
    directive.scope = {}; 
    directive.require = ["^parentDirective", "?ngModel"]; 
    directive.template = '<div></div>'; 
    directive.link = function (scope, elem, attrs, ctrl) { 
     var parentDirCtrl = ctrl[0]; 
     //allow parent scope(s) to $broadcast event 
     scope.$on(parentDirCtrl.events.setPlaceHolderText, 
      function (event, arg1, arg2) { 
       elem.html("$Broadcast: " + arg1 + " " + arg2); 
      }); 

     //Add function to parent controller 
     parentDirCtrl.setPlaceHolderText = function() { 
      elem.html("Added to parent controller!"); 
     } 
    }; 

    return directive; 
}); 

Если у вас есть несколько childDirectives и вы идете с добавлением функции в контроллер родительской директивы, вы должны принять меры предосторожности, потому что каждая дополнительная директива ребенка будет затирать на ctrl.setPlaceHolderText (то есть только один elem.html будет называться).

Библиотека bindonce использует что-то похожее на вторую технику, чтобы дочерние директивы добавляли «связующие» в родительскую директиву. Конкурирующая модель, вероятно, более чиста для ваших целей, но хотела предоставить другой вариант для директивной коммуникации.

0

Широковещательная передача не является предпочтительной, поскольку если имеется несколько экземпляров дочерней или дочерней комбинации дочерних или даже родительских потомков, вещание будет вызывать все.

Смежные вопросы