2013-10-13 11 views
20

Ich versuche, die Steuerung eines Elternteils „Box“ Richtlinie rekursiv zu erreichen:Wie kann der Controller der übergeordneten Richtlinie rekursiv angefordert werden?

<body ng-app="main"> 

<!-- no nesting: parent is the just body --> 
<box></box> 

<script type="text/javascript"> 
angular.module('main', []) 
.directive('box', function() { 
    return { 
     restrict: 'E', 
     controller: function() { }, 
     require: '?^box', // find optional PARENT "box" directive 
     link: function(scope, iElement, iAttrs, controller) { 
      // controller should be undefined, as there is no parent box 
      alert('Controller found: ' + (controller !== undefined)); 
     } 
    }; 
}); 
</script> 
</body> 

I Reglergröße erwarten würde undefined in der Link-Funktion sein, aber ich habe den Controller der Richtlinie tatsächlichen Box .

Also meine Frage ist ... wie, wie dieser Zugriff auf die übergeordneten Steuerung für den Fall zu gewinnen:

<box> 
    <box></box> 
</box> 

http://jsfiddle.net/gjv9g/1/

Antwort

18

OK, fand es ...

wenn Sie halten die Steuerung eines übergeordneten Elements erhalten möchten:

... 
link: function(scope, iElement, iAttrs, controller) { 
    // http://docs.angularjs.org/api/angular.element 
    // jQuery/jqLite Extras: 
    // 
    // controller(name) - retrieves the controller of the current element or its parent. 
    // By default retrieves controller associated with the ngController directive. 
    // If name is provided as camelCase directive name, then the controller for this 
    // directive will be retrieved (e.g. 'ngModel'). 
    var parentCtrl = iElement.parent().controller('box'); 
} 
... 

Dies gibt entweder Controller der Eltern-Richtlinie oder eine Ebene höher, die Controller der Eltern-Richtlinie der Eltern, wenn Sie Sie müssen sicherstellen, dass eine Steuerung eines DIRECT Eltern bekommen, fand ich diese (vielleicht gibt es eine bessere Lösung, ich weiß es nicht):

... 
controller: function($scope, $element) { 
    // store the element in controller, we'll need it later 
    this.$element = $element; 
}, 
// works in both pre and post link functions 
link: function() { 
    var parentElement = $element.parent(); 
    var parentCtrl = parentElement.controller('box'); 

    var hasDirectBoxParent = parentCtrl && parentCtrl.$element[0] === parentElement[0]; 

} 
... 

Beispiel 1:

<box id="a"> 
    <box id="b"></box> 
<box> 

Wenn die Link-Funktion auf "box a" aufgerufen wird, wird parentCtrl undefined in beiden Fällen. Wenn die Link-Funktion auf "Box b" aufgerufen wird, ist ParentCtrl in beiden Fällen der Controller von "Box a".

Beispiel 2:

<box id="a"> 
    <div> 
     <box id="b"></box> 
    </div> 
<box> 

Wenn die Link-Funktion auf "box a" aufgerufen wird, ist parentCtrl undefined in beiden Fällen. Wenn die Link-Funktion auf "Box b" aufgerufen wird, ist ParentCtrl immer noch der Controller von "Box a", aber hatDirectBoxParent ist false, so dass Sie Eltern von einem Großeltern unterscheiden können.

4

require spritzt den Controller aus der erforderlichen (übergeordneten) Richtlinie auf dem aktuelle Anweisung (aus der eckigen Dokumentation: "require - Erfordern eine andere Direktive und injizieren Sie seinen Controller als viertes Argument der Verknüpfungsfunktion" http://docs.angularjs.org/guide/directive)

Also vielleicht bist du schon getti was willst du? Das heißt, der übergeordnete Controller wird über den Parameter controller den Kindern hinzugefügt.

+0

wie Sie sehen können, gibt es keine ELTERN-Box in meinem ursprünglichen Beispiel, so erwarte ich 'undefined' als vierten Parameter auf die bekommen Linking-Funktion, nicht der Controller der Instanz selbst – maX

+0

Aber Sie erklären einen Controller. Also bekommt der Elternteil diesen Controller und die Kinder (falls vorhanden) erben von ihm. Ist Ihr Ziel zu wissen, ob eine bestimmte Richtlinie der Elternteil oder ein Kind ist? Wenn ja, möchtest du vielleicht den $ parent-Bereich betrachten? – KayakDave

+1

Eigentlich möchte ich in diesem speziellen Fall keinen Scope verwenden, da Scopes schwierig werden können, besonders wenn Sie einen isolierten Scope verwenden müssen. Darüber hinaus empfiehlt es sich, Controller zu verwenden und für die Kommunikation zwischen Direktiven zu verlangen. Mein Punkt ist, dass es wie ein Charme funktioniert, wenn Sie eine Eltern-Direktive mit einem anderen Namen benötigen, warum sollten Sie das nicht rekursiv tun können. – maX

39

Seit Angular 1.3 können Sie zwei Akzente ^^ verwenden, um nach einer Direktive in übergeordneten Elementen "nur" zu suchen.

Zitat aus dem Angular Docs on require:

  • (no prefix) - Suchen Sie den gewünschten Controller auf dem aktuellen Element. Einen Fehler werfen, wenn er nicht gefunden wird.
  • ? - Versuch, den erforderlichen Controller zu finden oder null an den Link fn zu übergeben, falls nicht gefunden.
  • ^ - Suchen Sie den erforderlichen Controller , indem Sie das Element und seine Eltern durchsuchen. Einen Fehler werfen, wenn er nicht gefunden wird.
  • ^^ - Suchen Sie den gewünschten Controller, indem Sie die Eltern des Elements durchsuchen. Einen Fehler werfen, wenn er nicht gefunden wird.
  • ?^ - Versuch, den erforderlichen Controller zu finden, indem das Element und seine Eltern durchsucht oder Null an den Link fn übergeben wird, falls nicht gefunden.
  • ?^^ - Versuch, den erforderlichen Controller zu finden, indem die Eltern des Elements durchsucht werden, oder Null an den Link fn übergeben, falls nicht gefunden.

In Ihrem Fall ersetzen require: '?^box', mit require: '?^^box',

Verwandte Themen