web-dev-qa-db-fra.com

AngularJS - Directives vs contrôleurs

J'essaie de créer ma première application en utilisant AngularJS. Cependant, je suis un peu confus si j'ai besoin d'utiliser des directives pour mon cas particulier.

J'ai une page de carte simple, où je dois montrer la valeur lat/lon de la région sélectionnée. Pour le moment, je n'utilise pas du tout de directives. Je fais tout dans le contrôleur et j'utilise des partiels pour afficher les résultats. Je ne prévois pas de réutiliser ma vue de carte dans un autre endroit. C'est pourquoi je ne pensais pas avoir besoin d'une directive.

D'un autre côté, j'ai lu quelque part que chaque fois que vous essayez de manipuler DOM dans votre contrôleur (ce que je fais en utilisant l'API Google Maps), vous devez déplacer cette partie vers les directives.

Voici mon contrôleur simple:

function MapViewController($scope) {
  $scope.zoom = 6;
  $scope.lat = 37;
  $scope.lon = -122;
  var mapOptions = {
    center: new google.maps.LatLng($scope.lat, $scope.lon),
    zoom: $scope.zoom,
    mapTypeId: google.maps.MapTypeId.HYBRID
  };
  $scope.map = new google.maps.Map(
      document.getElementById('map-canvas'), mapOptions);

  /*
   * Update zoom and other map attributes.
   */
  google.maps.event.addListener($scope.map, 'center_changed', function() {
    $scope.$apply(function () {
      $scope.zoom = $scope.map.getZoom();
      var center = $scope.map.getCenter();
      $scope.lat = center.lat();
      $scope.lon = center.lng();
      var bounds = $scope.map.getBounds();
      var northEast = bounds.getNorthEast();
      $scope.northEastLat = northEast.lat();
      $scope.northEastLon = northEast.lng();
      var southWest = bounds.getSouthWest();
      $scope.southWestLat = southWest.lat();
      $scope.southWestLon = southWest.lng();
    });
  });

  /*
   * Set zoom and other map attributes.
   */
  google.maps.event.addListener($scope.map, 'some event', function() {
    $scope.$apply(function () {
      ...
    });
  });

  /*
   * Add markers to map.
   */
  google.maps.event.addListener($scope.map, 'another event', function() {
    $scope.$apply(function () {
      ...
    });
  });

}

Et voici mes partiels:

  <div id="map-controllers" class="span4">
    <form class="form-horizontal">
      <div class="control-group">
        <label class="control-label" for="inputNumber">Zoom:</label>
        <div class="controls">
          <input type="text" class="input-mini" placeholder="zoom" value="{{ zoom }}">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="inputNumber">Latitude:</label>
        <div class="controls">
          <input type="text" class="input-large" placeholder="Latitude" value="{{ lat }}">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="inputNumber">Longitude:</label>
        <div class="controls">
          <input type="text" class="input-large" placeholder="Longitude" value="{{ lon }}">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="inputNumber">North East Latitude:</label>
        <div class="controls">
          <input type="text" class="input-large" placeholder="Latitude" value="{{ northEastLat }}">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="inputNumber">North East Longitude:</label>
        <div class="controls">
          <input type="text" class="input-large" placeholder="Longitude" value="{{ northEastLon }}">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="inputNumber">South West Latitude:</label>
        <div class="controls">
          <input type="text" class="input-large" placeholder="Latitude" value="{{ southWestLat }}">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="inputNumber">South West Longitude:</label>
        <div class="controls">
          <input type="text" class="input-large" placeholder="Longitude" value="{{ southWestLon }}">
        </div>
      </div>
    </form>
  </div>
37
mohi666

Voici une brève réponse autonome, avec des liens vers des documents officiels pour plus d'informations (définition de "services" ajoutée pour faire bonne mesure):

http://docs.angularjs.org/guide/controller

Dans Angular, un contrôleur est une fonction constructeur JavaScript utilisée pour augmenter la portée Angular).

Lorsqu'un contrôleur est connecté au DOM via le ng-controller directive, Angular instanciera un nouvel objet contrôleur, en utilisant la fonction constructeur du contrôleur spécifié. Une nouvelle portée enfant sera disponible en tant que paramètre injectable pour la fonction constructeur du contrôleur sous la forme $scope.

http://docs.angularjs.org/guide/directive

À un niveau élevé, les directives sont des marqueurs sur un élément DOM (comme un attribut, un nom d'élément ou une classe CSS) qui indiquent au compilateur HTML d'AngularJS ($compile) pour attacher un comportement spécifié à cet élément DOM ou même pour transformer l'élément DOM et ses enfants.

http://docs.angularjs.org/guide/services

Les services angulaires sont des objets substituables qui sont câblés ensemble à l'aide de l'injection de dépendance (DI). Vous pouvez utiliser des services pour organiser et partager du code dans votre application.

52
jtheletter

Je pense que vous ne devriez utiliser que des contrôleurs pour câbler les services, les dépendances et gérer la logique métier.

Les directives doivent être utilisées pour la manipulation du DOM, ce qui est idéal pour gérer les interactions des utilisateurs, par exemple ajouter/modifier un widget. Ce serait un motif anti d'ajouter cela à un contrôleur car ce n'est pas une préoccupation du contrôleur et il serait gonflé par d'autres fonctionnalités, il est assez facile de passer des valeurs (portée) de votre contrôleur à une directive si nécessaire.

Vous obtenez alors l'avantage de pouvoir placer votre directive d'ajout de widget dans d'autres endroits de votre application si nécessaire, et rend généralement la base de code plus facile à suivre comme suit Law of Demeter

Savoir quand et où séparer les fonctionnalités est l'une des choses les plus difficiles pour moi Angular vous ferez des erreurs mais cela devient plus facile avec la pratique.

Pour répondre à la question, vous devriez probablement le diviser en une ou plusieurs directives, mais c'est aussi une question de complexité.Si votre application est simple comme vous l'avez dit, vous trouverez peut-être ce que vous avez. Cela peut simplement devenir un cas de refactorisation lorsqu'une exigence change.

11
Nath

Mes pairs et moi avons rencontré une situation similaire lors de l'apprentissage d'AngularJS. J'ai mis en place ce tableau simple qui devrait donner à tout le monde un bon point de départ en fonction du type de fonctionnalité qu'ils essaient d'implémenter dans Angular. http://demisx.github.io/angularjs/2014/09/14/angular-what-goes-where.html

9
demisx