2015-03-11 3 views
5

Auf der Suche nach dem "besten" Weg zum Aufbau einer Angular App habe ich mehrere Best-Practice-Artikel gefunden. Mit diesem Eingang habe ich dies:Trennung der DOM-Manipulation von eckigen Controllern - Best Practice gesucht

angular.module('xApp', []) 
//..... some services, factories, controllers, .... 

.directive('dirNotification',[ function dirNotification() { 
    return { 
     scope: {}, 
     templateUrl: 'xNotification.html', 
     replace: true, 
     controller: 'CtrlNotification', 
     link: function($scope){ 
      // if this is 'DOM manipulation, should be done here ... ? 
      /* 
      $scope.$on('session.update',function(event, args) { 
       if (args == null) { 
        $scope.notificationdata.username = ""; 
        $scope.notificationdata.sid = ""; 
       } else { 
        $scope.notificationdata.username = args.username; 
        $scope.notificationdata.sid = args.accessToken; 
       } 
      }); 
      */ 
     } 

    }; 
}]) 
.controller('CtrlNotification',['$scope' ,function CtrlNotification($scope) { 

    $scope.notificationdata = { 
     username: "", 
     sid: "" 
    }; 

    // this is not real DOM manipulation, but only view data manipulation? 
    $scope.$on('session.update',function(event, args) { 
     if (args == null) { 
      $scope.notificationdata.username = ""; 
      $scope.notificationdata.sid = ""; 
     } else { 
      $scope.notificationdata.username = args.username; 
      $scope.notificationdata.sid = args.accessToken; 
     } 
    }); 

}]) 

Die HTML-Vorlage ist einfach:

<div> 
    <p>{{notificationdata.username}}</p> 
    <p>{{notificationdata.sid}}</p> 
</div> 

Also meine Frage ist, sollten Datenänderungen als DOM-Manipulation in Betracht gezogen werden? Die vorliegende Version, die dies innerhalb des Controllers macht, erscheint mir praktischer (z. B. das Setzen von Standardwerten). Wenn ich weitere Funktionen hinzufüge, wird der Block "directive link" erweitert und enthält mehr Funktionen als Definitionen. Ich denke, innerhalb der Direktive sollten Dinge wie das Ändern von Farben oder das Ausblenden von Elementen in Abhängigkeit von den Scope-Daten dort gemacht werden.

Was bedeutet die Gemeinschaft? Stimmen Sie meinen Annahmen zu?

Danke, Rainer

Antwort

7

Als guter Anfang, lesen Sie diese SO question/answer.

Controller:

Der Grund, warum Sie die DOM-Manipulation ist (was das betrifft oder Lookup von DOM-Elementen oder irgendwelche Annahmen über die Ansicht,) in der Steuerung nicht tun sollte, weil es die Absicht des Controllers ist es, sich nur mit dem Zustand der App zu befassen - indem Sie das ViewModel ändern - unabhängig davon, wie sich der Status in der View widerspiegelt. Dieser Controller führt dies durch, indem er auf Ereignisse aus dem Modell und aus den View- und Einstellungseigenschaften des ViewModel reagiert. Angular wird sich damit beschäftigen, den "Zustand" der App in der Ansicht mit Bindings zu reflektieren.

Also, natürlich, das Ändern des ViewModel bewirkt, dass die View reagiert und DOM manipuliert wird, aber die Idee ist, dass der Controller nicht wissen oder sich darum kümmern sollte, wie genau die View reagiert. Dies hält die Trennung von Anliegen intakt.

Richtlinien:

Bei Einbau-Richtlinien sind nicht genug, und Sie benötigen eine strengere Kontrolle über wie die Ansicht reagiert, ist dies ein guter Grund, eine eigene Richtlinie zu erstellen.

Zwei Dinge, die man sich über Direktiven merken sollte.

1) Es ist nützlich, Direktiven als wiederverwendbare Komponenten zu betrachten. Je weniger App-spezifische Logik es gibt, desto besser. Vermeiden Sie auf jeden Fall jede Geschäftslogik. Definieren Sie Inputs und Outputs (typischerweise über Attribute) und reagieren Sie nur auf diese. Ereignis-Listener (wie Sie) sind sehr anwendungsspezifisch (es sei denn, diese Anweisung soll mit einer anderen Direktive verwendet werden, die ein Ereignis veröffentlicht), also sollten Sie besser vermeiden, wenn möglich.

.directive("notification", function(){ 
    return { 
    restrict: "A", 
    scope: { 
     notification: "=" // let the attribute get the data for notification, rather than 
         // use scope.$on listener 
    }, 
    // ... 
    } 
}) 

2) Nur weil Direktiven „Manipulationen zu tun DOM erlaubt“ bedeutet nicht, dass Sie über die Trennung Ansichtsmodell-View vergessen sollte. Mit Angular können Sie den Bereich innerhalb einer Verknüpfung oder einer Controllerfunktion definieren und eine Vorlage mit allen typischen eckigen Ausdrücken und Bindungen bereitstellen.

template: '<div ng-show="showNotification">username:{{notification.username}}</div>', 

// controller could also have been used here 
link: function(scope, element, attrs){ 
    scope.showNotification = Math.floor(Math.random()* 2);  
} 
+0

Vielen Dank! Die ViewModel-Idee macht es in der Tat viel klarer. Lassen Sie mich ein wenig mehr lesen und spielen Sie mit Ihren Hinweisen für den Moment. – Rainer

+0

@Rainer, habe ich Ihre Frage adressiert? –

+0

Definitiv, nochmals vielen Dank! Entschuldigung, hoffentlich kann ich bald jeden Tag mit Angular arbeiten, momentan leider nicht. – Rainer