webentwicklung-frage-antwort-db.com.de

Link vs. Compile vs. Controller

Wenn Sie eine Direktive erstellen, können Sie Code in den Compiler, die Link-Funktion oder den Controller einfügen.

In den Dokumenten erklären sie Folgendes:

  • die Kompilierungs- und Verknüpfungsfunktion wird in verschiedenen Phasen des Zyklus angular verwendet
  • steuerungen werden von Richtlinien gemeinsam genutzt

Für mich ist jedoch nicht klar, welche Art von Code wohin gehen soll.

Zum Beispiel: Kann ich Funktionen beim Kompilieren erstellen und sie im Link an den Bereich anhängen oder nur Funktionen an den Bereich in der Steuerung anhängen?

Wie werden Controller zwischen Direktiven geteilt, wenn jede Direktive einen eigenen Controller haben kann? Sind die Controller wirklich gemeinsam oder sind es nur die Bereichseigenschaften?

524
schacki

Compile:

Dies ist die Phase, in der Angular Ihre Direktive kompiliert. Diese Kompilierungsfunktion wird für jeden Verweis auf die angegebene Direktive nur einmal aufgerufen. Angenommen, Sie verwenden die Anweisung ng-repeat. ng-repeat muss das Element suchen, an das es angehängt ist, das HTML-Fragment extrahieren, an das es angehängt ist, und eine Vorlagenfunktion erstellen.

Wenn Sie HandleBars, Unterstreichungsvorlagen oder Ähnliches verwendet haben, ist dies wie das Kompilieren der Vorlagen zum Extrahieren einer Vorlagenfunktion. An diese Vorlagenfunktion übergeben Sie Daten, und der Rückgabewert dieser Funktion ist der HTML-Code mit den Daten an den richtigen Stellen.

Die Kompilierungsphase ist der Schritt in Angular, der die Vorlagenfunktion zurückgibt. Diese Schablonenfunktion in angular wird als Verknüpfungsfunktion bezeichnet.

Verbindungsphase:

In der Verknüpfungsphase hängen Sie die Daten ($ scope) an die Verknüpfungsfunktion an und sollten den verknüpften HTML-Code zurückgeben. Da die Direktive auch angibt, wohin dieses HTML geht oder was es ändert, ist es bereits gut zu gehen. In dieser Funktion möchten Sie Änderungen an dem verknüpften HTML-Code vornehmen, d. H. Dem HTML-Code, an den die Daten bereits angehängt sind. Wenn Sie in angular Code in die Verknüpfungsfunktion schreiben, ist dies im Allgemeinen die Nachverknüpfungsfunktion (standardmäßig). Es ist eine Art Rückruf, der aufgerufen wird, nachdem die Verknüpfungsfunktion die Daten mit der Vorlage verknüpft hat.

Controller:

Der Controller ist ein Ort, an dem Sie eine direktivenspezifische Logik einfügen. Diese Logik kann auch in die Verknüpfungsfunktion eingehen, aber dann müssten Sie diese Logik auf den Gültigkeitsbereich setzen, um sie "gemeinsam nutzbar" zu machen. Das Problem dabei ist, dass Sie dann den Gültigkeitsbereich mit Ihren Direktiven-Dingen beschädigen würden, was eigentlich nicht zu erwarten ist. Was ist die Alternative, wenn zwei Richtlinien miteinander sprechen oder zusammenarbeiten möchten? Natürlich können Sie all diese Logik in einen Dienst einbauen und dann beide Anweisungen von diesem Dienst abhängig machen, aber das bringt nur eine weitere Abhängigkeit mit sich. Die Alternative besteht darin, einen Controller für diesen Bereich bereitzustellen (normalerweise Bereich isolieren?), Und dieser Controller wird dann in eine andere Direktive eingefügt, wenn diese Direktive die andere "erfordert". Ein Beispiel finden Sie in den Registerkarten und Fenstern auf der ersten Seite von angularjs.org.

469
ganaraj

Ich wollte auch hinzufügen, was das O'Reily AngularJS-Buch des Google-Teams zu sagen hat:

Controller - Erstellen Sie einen Controller, der eine API für die Kommunikation zwischen Direktiven veröffentlicht. Ein gutes Beispiel ist Mitteilung von Richtlinie zu Richtlinie

Verknüpfung - Ändern Sie die resultierenden DOM-Elementinstanzen programmgesteuert, fügen Sie Ereignis-Listener hinzu und richten Sie die Datenbindung ein.

Kompilieren - Ändern Sie programmgesteuert die DOM-Vorlage für Features in Kopien einer Direktive, wie in ng-repeat. Ihre Kompilierungsfunktion kann auch Verknüpfungsfunktionen zurückgeben, um die resultierenden Elementinstanzen zu ändern.

98
Nicholas Dynan

Mit directive können Sie das HTML-Vokabular deklarativ erweitern, um Webkomponenten zu erstellen. Das ng-app -Attribut ist eine Direktive, ebenso wie ng-controller und alle ng- prefixed attributes. Direktiven können attributes, tags oder sogar classnames, comments sein.

Wie Direktiven entstehen (compilation und instantiation)

Compile: Wir verwenden die Funktion compile sowohl für manipulate das DOM, bevor es gerendert wird, als auch für die Rückgabe einer Funktion link (die die Verknüpfung für uns übernimmt). Hier können Sie auch alle Methoden ablegen, die für alle instances dieser Direktive freigegeben werden müssen.

link: Mit der Funktion link registrieren wir alle Listener für ein bestimmtes DOM-Element (das aus der Vorlage geklont wurde) und richten unsere Bindungen für die Seite ein.

Wenn in der Funktion compile() eingestellt, wurden sie nur einmal eingestellt (was oft gewünscht wird). Wenn in der Funktion link() festgelegt, werden sie jedes Mal festgelegt, wenn das HTML-Element an Daten im Objekt gebunden wird.

<div ng-repeat="i in [0,1,2]">
    <simple>
        <div>Inner content</div>
    </simple>
</div>

app.directive("simple", function(){
   return {
     restrict: "EA",
     transclude:true,
     template:"<div>{{label}}<div ng-transclude></div></div>",        
     compile: function(element, attributes){  
     return {
             pre: function(scope, element, attributes, controller, transcludeFn){

             },
             post: function(scope, element, attributes, controller, transcludeFn){

             }
         }
     },
     controller: function($scope){

     }
   };
});

Die Funktion Compile gibt die Verknüpfungsfunktion pre und post zurück. In der Vorverknüpfungsfunktion haben wir die Instanzvorlage und auch den Gültigkeitsbereich aus dem controller, aber die Vorlage ist nicht an den Gültigkeitsbereich gebunden und hat noch keinen übertragenen Inhalt.

Bei der Link-Funktion Post wird die Funktion post link als letzte ausgeführt. Nun ist der transclusion vollständig, the template is linked to a scope und view will update with data bound values after the next digest cycle. Die Option link ist nur eine Verknüpfung zum Einrichten einer post-link -Funktion.

controller: Der Direktiven-Controller kann an eine andere Direktiven-Verknüpfungs-/Kompilierungsphase übergeben werden. Es kann in andere Direktiven als Mittel zur Verwendung in der Kommunikation zwischen Direktiven eingespeist werden.

Sie müssen den Namen der Direktive angeben, die erforderlich sein soll. Sie muss an dasselbe Element oder an das übergeordnete Element gebunden sein. Dem Namen kann Folgendes vorangestellt werden:

? – Will not raise any error if a mentioned directive does not exist.
^ – Will look for the directive on parent elements, if not available on the same element.

Verwenden Sie die eckige Klammer [‘directive1′, ‘directive2′, ‘directive3′], um mehrere Controller-Anweisungen zu benötigen.

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope, $element) {
});

app.directive('parentDirective', function() {
  return {
    restrict: 'E',
    template: '<child-directive></child-directive>',
    controller: function($scope, $element){
      this.variable = "Hi Vinothbabu"
    }
  }
});

app.directive('childDirective', function() {
  return {
    restrict:  'E',
    template: '<h1>I am child</h1>',
    replace: true,
    require: '^parentDirective',
    link: function($scope, $element, attr, parentDirectCtrl){
      //you now have access to parentDirectCtrl.variable
    }
  }
});
51
Thalaivar

Ein guter Grund für die Verwendung einer Controller/Link-Funktion (da beide Zugriff auf den Bereich, das Element und die Attribute haben) ist, dass Sie einen verfügbaren Dienst oder eine Abhängigkeit in beliebiger Reihenfolge an einen Controller übergeben können Mit der Link-Funktion ist das nicht möglich. Beachten Sie die unterschiedlichen Signaturen:

controller: function($scope, $exceptionHandler, $attr, $element, $parse, $myOtherService, someCrazyDependency) {...

vs.

link: function(scope, element, attrs) {... //no services allowed
12
ScaryBunny

dies ist ein gutes Beispiel für das Verständnis der Direktivenphasen http://codepen.io/anon/pen/oXMdBQ?editors=101

var app = angular.module('myapp', [])

app.directive('slngStylePrelink', function() {
    return {
        scope: {
            drctvName: '@'
        },
        controller: function($scope) {
            console.log('controller for ', $scope.drctvName);
        },
        compile: function(element, attr) {
            console.log("compile for ", attr.name)
            return {
                post: function($scope, element, attr) {
                    console.log('post link for ', attr.name)
                },
                pre: function($scope, element, attr) {
                    $scope.element = element;
                    console.log('pre link for ', attr.name)
                        // from angular.js 1.4.1
                    function ngStyleWatchAction(newStyles, oldStyles) {
                        if (oldStyles && (newStyles !== oldStyles)) {
                            forEach(oldStyles, function(val, style) {
                                element.css(style, '');
                            });
                        }
                        if (newStyles) element.css(newStyles);
                    }

                    $scope.$watch(attr.slngStylePrelink, ngStyleWatchAction, true);

                    // Run immediately, because the watcher's first run is async
                    ngStyleWatchAction($scope.$eval(attr.slngStylePrelink));
                }
            };
        }
    };
});

html

<body ng-app="myapp">
    <div slng-style-prelink="{height:'500px'}" drctv-name='parent' style="border:1px solid" name="parent">
        <div slng-style-prelink="{height:'50%'}" drctv-name='child' style="border:1px solid red" name='child'>
        </div>
    </div>
</body>
10
Amin Rahimi
  • compile: Wird verwendet, wenn Sie eine Anweisungsvorlage ändern müssen, z. B. einen neuen Ausdruck hinzufügen oder eine andere Anweisung innerhalb dieser Anweisung anhängen möchten
  • controller: Wird verwendet, wenn wir $ scope-Daten freigeben/wiederverwenden müssen
  • link: Dies ist eine Funktion, die verwendet wird, wenn Event-Handler hinzugefügt oder DOM bearbeitet werden müssen.
4
HamidKhan