Blog & News

AngularJS ControllerAs mit Direktiven

Genau wie bei ng-controller und bei einer Route-Definition mittels ngRoute und UI Router steht uns die ControllerAs-Schreibweise auch in Direktiven zur Verfügung. Wer mehr über die ControllerAs-Schreibweise erfahren möchte, kann hier (ng-controller mit ControllerAs) und hier (ControllerAs mit Route-Definition) darüber lesen.

Beispiel: Direktive mit ControllerAs

Ausschnitt aus index.html

<body ng-app="direktiveMitCtrlAs">
  <meine-direktive></meine-direktive>
</body>

script.js

angular.module('direktiveMitCtrlAs', [])
  .directive('meineDirektive', function() {
    return {
      controller: 'DirCtrl',
      controllerAs: 'dirCtrl',
      template: '<h1>Ich bin eine Direktive</h1><div>Name: {{dirCtrl.name}}</div>'
    };
  })
  .controller('DirCtrl', function() {
    this.name = 'MeineDirektive';
  });

Plunker Link für das Beispiel

Im Beispiel haben wir eine Direktive namens „meineDirektive“ definiert, und in der index.html-Datei nutzen wir diese Direktive. Wenn jetzt dieser Code in den Browser geladen wird, wird statt {{dirCtrl.name}} der Wert angezeigt, den wir für this.name im Controller angegeben haben. Das ist die einfachste Form, eine Direktive mit ControllerAs zu definieren und zu nutzen. Dies ist auch der erste Schritt zur einer komponentenbasierten Anwendung. In diesem Fall ist eine Komponente eine Direktive mit einer View (template oder templateUrl) und einem Controller. So werden auch Komponenten in AngularJS 2 definiert, obwohl dort die Schreibweise eine andere ist. Den Controller in der Direktive zu definieren hat den Vorteil, dass man genau sieht, welcher Controller verantwortlich für die View der Direktive ist. Vermutlich wird es auch einfacher, eine solche Direktive in eine AngularJS 2-Komponente umzuschreiben.

Manch einer fragt sich jetzt wahrscheinlich, was passiert, wenn wir mit einem isoliertem Scope arbeiten. Wie kommen wir da an die Daten, ohne einen $scope in den Controller zu injizieren. Zum Glück hat Angular eine Antwort auf diese Frage; sie lautet bindToController.

Beispiel: Direktive mit ControllerAs und isoliertem Scope

Ausschnitt aus index.html

<body ng-app="direktiveMitCtrlAs">
  <div ng-controller="MainCtrl as main">
    <meine-direktive name="main.name"></meine-direktive>
  </div>
</body>

script.js

angular.module('direktiveMitCtrlAs', [])
  .directive('meineDirektive', function() {
    return {
      controller: 'DirCtrl',
      controllerAs: 'dirCtrl',
      scope: {
        name: '='
      },
      bindToController: true,
      template: '<h1>Ich bin eine Direktive</h1><div>Name: {{dirCtrl.name}}</div><div>Internal Name: {{dirCtrl.internalName}}</div>'
    };
  })
  .controller('MainCtrl', function() {
    this.name = 'MainCtrl';
  })
  .controller('DirCtrl', function() {
    this.internalName = 'MeineDirektive';
  });

Plunker Link für das Beispiel

Mit Hilfe von bindToController haben wir die Eigenschaften des Scope an unseren dirCtrl statt an den Scope gebunden. Somit können wir diese Eigenschaften über den dirCtrl-Namespace nutzen, wie wir im Template sehen können. Achtung: Die name-Eigenschaft befindet sich nicht mehr im Scope, und somit haben wir auch kein Zugriff auf die Eigenschaft über den scope-Parameter der link-Funktion. Wer den Zugriff auf diese Eigenschaft braucht, kann den vierten Parameter der link-Funktion nutzen. Sofern die Direktive die require-Eigenschaft nicht besitzt, ist der vierte Parameter der Controller der Direktive. Mit Angular 1.4 haben wir noch eine weitere Möglichkeit, externe Eigenschaften an den Controller einer Direktive zu binden und wir können dort ControllerAs auch mit nicht isoliertem Scope nutzen. Aber dies soll in einem anderen Blogartikel behandelt werden.

Nikolas Poniros
AUTOR

Nikolas Poniros

Bietet mehrjährige Projekterfahrung in der Webentwicklung mit JavaScript