07. Le module show: édition d'une série
Après avoir affiché la liste des séries gérées dans notre application, nous allons maintenant créer une vue permettant de modifier ou ajouter de nouvelles séries.
Enrichissement du service
Pour pouvoir gérer cette fonctionnalité, nous allons devoir ajouter dans showService deux méthodes :
- Une pour récupérer un élément spécifique getShow(id)
- Une pour enregistrer ou mettre à jour un élément saveShow(show)
var getShows, // = ...
// récupération de la série identifiée par: id
getShow = function (id) {
var deferred = $q.defer();
// récupération de la liste des séries
getShows().then(function (shows) {
var i = shows.length, show;
while (i--) {
if (shows[i].id == id) {
show = shows[i];
break;
}
}
if(show) {
deferred.resolve(show);
} else {
deferred.reject();
}
}, function (response) {
deferred.reject(response);
});
return deferred.promise;
},
// sauvegarde d'une série
saveShow = function (show) {
var deferred = $q.defer();
// récupération de la liste des séries
getShows().then(function (shows) {
if (show.id) { // s'il y a un id, c'est une mise à jour
var i = shows.length, idx = 0;
// recherche de l'index de l'élément dans le tableau
while (i--) {
if (shows[i].id == show.id) {
idx = i;
break;
}
}
// remplacement de l'élément
shows.splice(idx, 1, show);
} else { // sinon si pas d'id ajout d'un nouvel élément
var i = shows.length, id = 0;
// génération d'un id
while (i--) {
id = Math.max(id, shows[i].id);
}
show.id = id + 1;
// ajout de l'élément
shows.push(show);
}
deferred.resolve(show);
}, function (response) {
deferred.reject(response);
});
return deferred.promise;
};
return {
getShows: getShows,
deleteShow: deleteShow,
getShow: getShow,
saveShow: saveShow
};
Création du controller
Nous allons dans le module show ajouter un deuxième controller qui va également injecter le service.
En plus, nous ajouterons deux services d’Angular :
- $routeParams qui permet de récupérer les paramètres de la route
- $location qui permettra de rediriger l’utilisateur vers la liste des séries après un enregistrement
// src/modules/show/controllers/ShowEditController.js
'use strict';
app.controller('ShowEditController', ['$location', '$routeParams', 'showService', function($location, $routeParams, showService) {
var vm = this;
vm.show = {};
// s'il y a un id dans les paramètres de la route on charge la série correspondante
if ($routeParams.id) { // /show/:id?
showService.getShow($routeParams.id).then(function (show) {
vm.show = show;
});
} else {
// sinon on ne récupère rien; c'est alors un ajout
}
// methode appelée pour sauvegarder
vm.saveShow = function (showForm) {
showService.saveShow(vm.show).then(function () {
toastr.success('Save success');
// en cas de succès, redirige l'utilisateur vers la liste
$location.path('/shows')
}, function(error){
toastr.error('Save error !');
});
};
}
]);
Attention, ne pas oublier d'inclure le fichier js correspondant à ce nouveau controller
Le formulaire
Après avoir créé le controller, ajoutons une vue (src/module/show/views/show-edit.html) correspondante qui contiendra un formulaire pour modifier ou ajouter une série.
Angular enrichit les formulaires de nombreuses propriétés permettant de faciliter notamment la validation. Pour cela, il faut donner un nom au formulaire (ici showForm). Nous avons alors accès à :
- showForm.field.$invalid indique que le champ n'est pas valide
- showForm.field.$dirdy indique que le champ a commencé à être modifié
Ainsi, en jouant avec ces deux propriétés, on peut mettre en avant à destination de l’utilisateur, que sa saisie n’est pas valide très facilement.
<div>
<h1>Show <small>Edit</small></h1>
<form name="showForm" ng-submit="editCtrl.saveShow(showForm)" novalidate>
<hr />
<h2>Show properties</h2>
<div class="form-horizontal">
<div class="form-group" ng-class="{'has-error' : showForm.title.$invalid && showForm.title.$dirty}">
<label for="title" class="control-label col-sm-2">Title:</label>
<div class="col-sm-10">
<input id="title" name="title" type="text" class="form-control" ng-model="editCtrl.show.title" required/>
</div>
</div>
<div class="form-group" ng-class="{'has-error' : showForm.year.$invalid && showForm.year.$dirty}">
<label for="year" class="control-label col-sm-2">Year:</label>
<div class="col-sm-10">
<input id="year" name="year" type="number" class="form-control" ng-model="editCtrl.show.year"/>
</div>
</div>
<hr />
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4 col-xs-12">
<input class="btn btn-lg btn-primary" type="submit" value="Save" ng-disabled="showForm.$invalid"/>
<a class="btn btn-lg btn-default" href="#/shows">Annuler</a>
</div>
</div>
</div>
<!-- permet de voir toutes les propriétés liées au formulaire -->
<pre>{{showForm | json }}</pre>
</form>
</div>
En plus d'enrichir chaque champ, Angular ajoute également des propriétés au niveau global ce qui permet de désactiver le bouton sauvegarder tant que le formulaire n'est pas valide grâce à **showForm.$invalid**.
Pour facilement débugger un élément, vous pouvez utiliser le filte json sur une variable, se qui permet de voir facilement tout son contenu.
<pre>{{maVariable | json }}</pre>
Conlusion
Nous pouvons maintenant lister, ajouter et modifier des séries. Il ne reste plus qu’à ajouter des saisons et épisodes afin de suivre notre progression.