I. Avant-propos

Dans le précédent tutoriel, nous avons travaillé sur l'extraction et l'analyse des flux avec YQL en utilisant le service $http d'AngularJS (version 2e15d97).

Cette fois-ci, vous en apprendrez plus sur la liaison de données en ajoutant certains champs input pour permettre aux flux d'être ajoutés et supprimés.

Vous pouvez obtenir la source sur alexyoung/djsreader en version c9f9d06.

II. Modéliser plusieurs flux

La partie précédente mappe un flux à une vue en utilisant l'objet $scope.feed. Maintenant, nous voulons prendre en charge plusieurs flux, nous aurons besoin d'un moyen de modéliser des collections de flux ordonnées.

Pour ce faire, la méthode la plus simple consiste simplement à utiliser un tableau. Les objets qui contiennent les articles publiés et les URL peuvent être insérés dans le tableau :

 
Sélectionnez
$scope.feeds = [{
  url: 'http://dailyjs.com/atom.xml',
  items: [ /* Les articles de blogs */ ]
}];

III. Afficher plusieurs flux

La vue doit maintenant être modifiée pour utiliser des flux multiples au lieu d'un seul flux. Ceci peut être réalisé en utilisant la directive ng-repeat pour itérer sur chacun d'eux (app/views/main.html) :

 
Sélectionnez
<div ng-repeat="feed in feeds">
  <ul>
    <li ng-repeat="item in feed.items"><a href=""></a></li>
  </ul>
  URL : <input size="80" ng-model="feed.url">
  <button ng-click="fetchFeed(feed)">Actualiser</button>
  <button ng-click="deleteFeed(feed)">Supprimer</button>
  <hr />
</div>

Les méthodes fetchFeed et deleteFeed sont ajoutées au $scope dans le contrôleur, mais on s'en occupera plus tard. Tout d'abord, nous allons ajouter un formulaire pour créer un nouveau flux.

IV. Ajouter un flux

La vue pour l'ajout de flux a besoin d'utiliser une directive de ng-model pour lier une valeur afin que le contrôleur puisse accéder à l'URL du nouveau flux :

 
Sélectionnez
<div>
  URL : <input size="80" ng-model="newFeed.url">
  <button ng-click="addFeed(newFeed)">Ajouter un flux</button>
</div>

La méthode addFeed se déclenchera lorsque le bouton est cliqué. Tout ce que nous devons faire est de pousser newFeed dans $scope.feed puis de vider newFeed, donc le formulaire va être restauré à son état précédent. La méthode addFeed est également ajoutée à $scope dans le contrôleur (app/scripts/controllers/main.js) comme ceci :

 
Sélectionnez
$scope.addFeed = function(feed) {
  $scope.feeds.push(feed);
  $scope.fetchFeed(feed);
  $scope.newFeed = {};
};

Cet exemple pourrait être écrit en utilisant $scope.newFeed au lieu de l'argument feed. Mais ne pensez-vous pas que c'est mieux lorsque les arguments peuvent être passés à la vue juste en les ajoutant à la directive ?

V. Récupérer les flux

Le code original de $http devrait être transformé en une méthode pour être appelé par la directive ng-click sur le bouton :

 
Sélectionnez
$scope.fetchFeed = function(feed) {
  feed.items = [];

  var apiUrl = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'";
  apiUrl += encodeURIComponent(feed.url);
  apiUrl += "'%20and%20itemPath%3D'feed.entry'&format=json&diagnostics=true&callback=JSON_CALLBACK";

  $http.jsonp(apiUrl).
    success(function(data, status, headers, config) {
      if (data.query.results) {
        feed.items = data.query.results.entry;
      }
    }).
    error(function(data, status, headers, config) {
      console.error('Erreur lors de la récupération des flux :', data);
    });
};

L'argument feed sera le même que celui du tableau $scope.feeds, donc, en vidant l'ensemble des flux courants à l'aide de feed.items = [];, l'utilisateur verra une rétroaction instantanée lors du clic sur « Actualiser ». Ce qui rend plus facile de voir ce qui se passe si l'URL du flux est convertie en une autre URL.

J'ai utilisé encodeURIComponent pour coder l'URL du flux, elle peut ainsi être insérée en toute sécurité comme un paramètre de requête pour le service de Yahoo!.

VI. Supprimer le flux

Le contrôleur a également besoin d'une méthode pour supprimer les flux. Étant donné que nous travaillons en collaboration avec un tableau, nous pouvons utiliser splice sur l'objet :

 
Sélectionnez
$scope.deleteFeed = function(feed) {
  $scope.feeds.splice($scope.feeds.indexOf(feed), 1);
};

VII. Mises à jour périodiques

Actualiser automatiquement les flux RSS est un cas intéressant en AngularJS car il peut être implémenté à l'aide du service $timeout. C'est simplement une encapsulation de setTimeout, mais il délègue également des exceptions à $exceptionHandler.

Pour l'utiliser, ajoutez le à la liste d'arguments dans le contrôleur et définissez une valeur par défaut :

 
Sélectionnez
angular.module('djsreaderApp')
  .controller('MainCtrl', function($scope, $http, $timeout) {
    $scope.refreshInterval = 60;

Maintenant, faites en sorte que fetchFeed s'appelle lui-même à la fin de la méthode :

 
Sélectionnez
$timeout(function() { $scope.fetchFeed(feed); }, $scope.refreshInterval * 1000);

J'ai multiplié la valeur par 1000 donc il convertit les secondes (valeur encodée à l'écran) en millisecondes (valeur demandée par la méthode), ce qui rend la vue plus facile à comprendre :

 
Sélectionnez
<p>Actualiser (en secondes) : <input ng-model="refreshInterval"></p>
Image non disponible

VIII. Conclusion

Maintenant vous pouvez ajouter plus de flux au lecteur, ça commence à devenir une vrai application Web. Dans les prochains tutoriels, je vais ajouter des tests et une meilleure interface.

La version pour ce tutoriel est la c9f9d06.

IX. Remerciements

Cet article a été publié avec l'aimable autorisation de Alex Young. L'article original peut être lu sur le site DailyJSDailyJS : AngularJS: Managing FeedsAngularJS: Managing Feeds.

Je remercie égalementMax pour sa relecture attentive et assidue.