2016-08-04 12 views
1

Ich habe drei Angular 1.5 Komponenten: ReportFilter und ClientSelect, ZoneSelect.Wie kann ich auf den Controller einer verschachtelten Komponente von der übergeordneten Komponente zugreifen?

ReportFilter weist die beiden Komponenten in der es

<!-- Report Filter --> 
<div> 
    <client-select client="$ctrl.selections.client"></client-select> 
    <zone-select zone="$ctrl.selections.zone"></zone-select> 
    <button ng-click="$ctrl.search()">Get Report</button> 
    <button ng-click="$ctrl.clear()">Clear</button> 
</div> 

client und zone sind Zwei-Wege-Daten gebunden ist, so dass, wenn der Benutzer einen Client oder eine Zone auswählt, die jeweiligen Eigenschaften in meinem ReportFilter aktualisiert ' s Auswahlen.

Meine Frage:

Wie kann ich eine reset() Methode auf dem Controller meiner ClientSelect oder ZoneSelect Komponenten aus dem Inneren des ReportFilter ‚s Controller nennen?

React verfügt über ein ref-Tag, mit dem Sie Zugriff auf den Controller erhalten, um Methoden darauf aufzurufen.

Antwort

1

Ich glaube, der bevorzugte Ansatz ist in Ihrem Kind Richtlinie nehmen Sie einen Bereich Attribut namens api hinzufügen:

app.directive('childDirective', function() { 
    return { 
    scope: { 
     api: "=?" 
    }, 
    link: function(scope, elem, attrs) { 
     return { 
     scope.someFN = function() { 
      // do stuff. 
     }; 

     scope.api = { 
     someFN: scope.someFN 
     }; 
     }; 
    }; 
    }; 
}); 

Dann, wenn Sie die Anweisung rufen Sie einfach Attribut einen Bereich passieren:

<div ng-controller="parentCtrl"> 
    <child-directive api="foo"></child-directive> 
</div> 

Und Sie können jetzt anrufen Funktionen von der übergeordneten Steuerung mit

$scope.foo.someFN() 
+0

ich mehrere andere Komponenten (wie UI-Grid) verwenden diesen Ansatz gesehen habe als Gut. – sflogen

+0

Ich habe einige seltsame Verhaltensweisen bei einigen Bibliotheken bemerkt, die dies tun ... zum Beispiel erfordert angular-nvd3 normalerweise, dass Sie eine 'on-ready'-Funktion bereitstellen, um die Scope-Variable tatsächlich zu füllen. – aaronmallen

+0

Ich bin mir nicht sicher, ob dies das beabsichtigte Verhalten ist, da angle-nvd3 es Ihnen auch erlaubt, api zu definieren, aber es scheint nicht wirklich die Variable zu füllen, es sei denn, Sie tun dies innerhalb der On-Ready-Funktion. – aaronmallen

2

T hier ist keine integrierte Möglichkeit (im Gegensatz zu reagieren, wie Sie :)

Eine mögliche Lösung erwähnen ist die Kinder benötigen, um ihre Eltern zu lassen, und registrieren Sie sich, um es:

// child directive 
    .directive('clientSelect', function() { // `.component` is similar... 
     return { 
      ... 
      controller: ClientSelect, 
      require: ['clientSelect', 'reportFilter'], 
      link: function(scope, elem, attrs, ctrls) { 
       ctrls[1].setClientSelect(ctrls[0]); 
       // do not forget to deregister, just in case 
       scope.$on('$destroy', function() { 
        ctrls[1].setClientSelect(null); 
       }); 
      } 
     }; 
    }) 

    // parent directive 
    .directive('reportFilter', function() { 
     function ReportFilter() { 
      ... 
     } 

     ReportFilter.prototype.setClientSelect = function(clientSelect) { 
      this.clientSelect = clientSelect; 
     }; 

     ReportFilter.prototype.somethingElse = function() { 
      // reset the clientSelect: 
      this.clientSelect.reset(); 
     }; 

     return { 
      ... 
      controller: ReportFilter, 
      ... 
     }; 
    }) 

Wenn Sie nicht wollen die Kopplung zwischen den Kindern und den Elternkomponenten, dann können Sie die Kinder neu gestalten, so dass alle ihre Daten, und ich meine alle, die gesamte Sache, von ihren Eltern kommen. In diesem Fall wird die clientSelect zurückgesetzt werden, sondern nur die übergeordnete Steuerung die Daten, die er mit ihm teilt löschen muss, also zB:

// in the parent controller 
this.selections.client = {}; // or null or... 
+0

Ich mag diesen Ansatz, abgesehen von der Tatsache, dass die Richtlinie jetzt von einem bestimmten Controller abhängig ist. – aaronmallen

+1

Diese Kopplung ist in der Tat schlecht, wenn die Richtlinien unabhängige Komponenten sein sollen. Dies ist jedoch nicht der Fall, wenn sie aus einer Usability-Perspektive zusammenarbeiten sollen. Z.B. Knoten in einem Baum sind immer Teil eines ... Baumes. Die Anforderung ihrer übergeordneten "Baum" -Komponente führt zu keiner weiteren Kopplung. –

+0

Diese Idee _could_ funktioniert, aber ich plane, die 'clientSelect' und' reportFiler' Komponenten an anderen Stellen neben dem 'ReportFilter' zu verwenden. – sflogen