Kommunikation zwischen verschachtelten Anweisungen

61

Es scheint einige Möglichkeiten zu geben, zwischen Richtlinien zu kommunizieren. Angenommen, Sie haben verschachtelte Anweisungen, bei denen die inneren Anweisungen dem äußeren etwas mitteilen müssen (z. B. vom Benutzer ausgewählt).

<outer>
  <inner></inner>
  <inner></inner>
</outer>

Bisher habe ich 5 Möglichkeiten, dies zu tun

require: übergeordnete Richtlinie

Die innerDirektive kann die outerDirektive erfordern , die eine Methode auf ihrem Controller verfügbar machen kann. Also in der innerDefinition

require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
   // This can be passed to ng-click in the template
   $scope.chosen = function() {
     outerController.chosen(something);
   }
}

Und im outerController der Direktive:

controller: function($scope) {
   this.chosen = function(something) {
   }
}

$emit Veranstaltung

Die innerDirektive kann $emitein Ereignis sein, auf das die outerDirektive über reagieren kann $on. Also im innerController der Direktive:

controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}

und im outerDirektiven Controller:

controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}

Führen Sie den Ausdruck im übergeordneten Bereich über aus &

Das Element kann an einen Ausdruck im übergeordneten Bereich gebunden und an einer geeigneten Stelle ausgeführt werden. Das HTML wäre wie folgt:

<outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>

Der innerController hat also eine 'innerChoose'-Funktion, die er aufrufen kann

scope: {
  'innerChoose': '&'
},
controller: function() {
  $scope.click = function() {
    $scope.innerChoose({item:something});
  }
}

Dies würde (in diesem Fall) die 'functionOnOuter'-Funktion für den outerGeltungsbereich der Direktive aufrufen :

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

Bereichsvererbung im nicht isolierten Bereich

Da es sich um verschachtelte Controller handelt, kann die Bereichsvererbung aktiv sein, und die innere Direktive kann nur Funktionen in der Bereichskette aufrufen, sofern sie keinen isolierten Bereich hat. Also in der innerRichtlinie:

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}

Und in der outerRichtlinie:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

Durch Service in Innen und Außen gespritzt

Ein Dienst kann in beide Direktiven eingefügt werden, sodass sie direkten Zugriff auf dasselbe Objekt haben oder Funktionen aufrufen können, um den Dienst zu benachrichtigen, und sich möglicherweise sogar registrieren, um in einem Pub / Sub-System benachrichtigt zu werden. Dies erfordert nicht, dass die Direktiven verschachtelt sind.

Frage : Was sind mögliche Nachteile und Vorteile der beiden gegenüber den anderen?

Michal Charemza
quelle
5
Ich kann nicht glauben, dass ich diese Frage noch nicht gesehen habe. Ich schätze alle Optionen, die Sie zur Verfügung gestellt haben. Haben Sie schon einmal darüber nachgedacht, diese Frage auf stackoverflow zu stellen? Ich würde erwarten, dass es beim Stackoverflow viel mehr Traktion bekommt.
Mike Barlow - BarDev
Bitte beachten Sie diesen Vorschlag - softwareengineering.stackexchange.com/questions/344165/…
yellowblood

Antworten:

7

Ich bevorzuge es, ein &Attribut im Geltungsbereich der Direktive zu definieren, hauptsächlich, weil ich die scope: {}Definition einer Direktive als API sehe . Es ist viel einfacher, eine Bereichsattributdefinition zu betrachten, um festzustellen, welche Informationen die Direktive benötigt, um ordnungsgemäß zu funktionieren, als Link- und Controller-Funktionen nach $emitEreignissen, geerbten Bereichsfunktionen oder Funktionen zu durchsuchen , die in injizierten Controllern verwendet werden.

Jeff Swensen
quelle
1

Meine Meinung:

Dienste sind die bevorzugte Methode zum Austausch von Verhalten / Daten zwischen Modulen / Direktiven / Controllern. Direktiven sind isolierte Dinge, die verschachtelt sein können oder nicht. Controller sollten sich so weit wie möglich an ein Ansichtsmodell halten. Idealerweise sollte keine Geschäftslogik darin landen.

Damit:

Wenn Sie sie miteinander verbinden, indem Sie auf übergeordnete Bereichsfunktionen zugreifen, besteht meines Erachtens die Gefahr, dass sie zu stark gekoppelt werden und die gesamte Anwendung unleserlich wird und Komponenten nicht wiederverwendbar sind. Wenn Sie diese gemeinsam genutzten Daten oder Verhaltensweisen in einem Dienst entkoppeln, können Sie die gesamten Anweisungen mit unterschiedlichen Daten / Verhaltensweisen wiederverwenden und sogar den zur Laufzeit zu verwendenden Dienst bestimmen. Worum geht es bei der Abhängigkeitsinjektion?

RobbyD
quelle