2014-12-18 25 views
7

Jak wywołać metodę zdefiniowaną w dyrektywie potomnej, w ramach detektora nadrzędnego dyrektywy nadrzędnej.Wywołanie funkcji dyrektywy potomnej z dyrektywy nadrzędnej w 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; 
}) 

chcę zadzwonić dyrektywa dziecko setPlaceholderText(), gdy 'scope.createTodo()' dyrektywy rodzic jest tzw.

Jak można to zrobić.

+0

Jaki jest twój konkretny przypadek użycia? Co próbujesz? – Patrick

+0

@Patrick dodałem więcej szczegółów. Przepraszam, że nie było mojego systemu, więc nie mogłem dodać tego na czas. – jsbisht

Odpowiedz

3

W swoim dyrektywy macierzystej

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

W swoim dyrektywy dziecięcej

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

Dzięki Mathew. Czy miałoby to zastosowanie, gdyby dyrektywy wyodrębniły zakres? – jsbisht

2

Można $ nadawane zdarzenie do zakresów podrzędnych (jak wspomniano), lub można również dodać funkcję do rodzica kontroler dyrektywy z dyrektywy dotyczącej dziecka.

Oto jsfiddle z przykładami dyrektywy $ broadcast na child i przy użyciu techniki kontrolera.

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; 
}); 

Jeśli masz wiele childDirectives i udać się z dodanie funkcji do dyrektywy rodzic kontrolera, trzeba będzie podjąć środki ostrożności, ponieważ każda dodatkowa dyrektywa dziecko sprać na ctrl.setPlaceHolderText (czyli tylko jeden elem.html byłyby nazwie).

Biblioteka korzysta z czegoś podobnego do drugiej techniki, aby umożliwić dyrektywom dziecięcym dodanie "segregatorów" do dyrektywy nadrzędnej. Wdrażający model jest prawdopodobnie bardziej przejrzysty dla twoich celów, ale chciał podać inną opcję komunikacji w dyrektywie.

0

Emisja nie jest preferowana, ponieważ w przypadku wielu wystąpień kombinacji podrzędnej lub nawet rodzicielskiej podrzędnej, transmisja wyzwoli wszystkie.

Powiązane problemy