web-dev-qa-db-fra.com

Bonne pratique AngularJS REST / CRUD

Quelle est la meilleure pratique pour effectuer des opérations CRUD via REST avec AngularJS?

En particulier, quel est le Angular-Way ici. J'entends par là la façon d'utiliser le le moins de code et le le plus par défaut angular pour y parvenir.

Je connais $ resource et ses opérations par défaut. Je ne sais pas trop comment implémenter/nommer les points de terminaison et quels contrôleurs utiliser.

Pour cet exemple, je voudrais mettre en œuvre un système de gestion des utilisateurs simple qui crée/met à jour/supprime/répertorie les utilisateurs. Puisque j'implémente moi-même les points de terminaison de serveur, je suis totalement libre de le faire de la manière la plus angular conviviale.

Ce que j'aime comme réponse est quelque chose comme:

Points de terminaison du serveur:

GET /service/users -> array of users
GET /service/user/new -> return an empty user with default values which has no id
POST /service/user/new -> store a new user and create an id. return the saved user.
POST /service/user/:ID -> save an existing user. Return the saved user
DELETE /service/user/:ID -> delete an existing user

Angular-Services:

.factory( 'User', [ '$resource', function( $resource ){

    return $resource( '/service/user/:userId', { userId: '@id' } )
    [...]

}])

Routage:

.when( '/users', {
    templateUrl: BASE + 'partials/user-list.html',
    controller: 'UserListCtrl' } )

.when( '/user/new', {
    templateUrl: BASE + 'partials/user-edit.html',
    controller: 'UserNewCtrl' } )

.when( '/user/:userId', {
    templateUrl: BASE + 'partials/user-edit.html',
    controller: 'UserEditCtrl' } )
...

Contrôleurs:

UserListCtrl:

    $scope.data = User.get(...)

UserNewCtrl:

    $scope.user = User.get( { userId: "new" } )

...

Notez que je ne suis pas intéressé par l'opinion quelle est la meilleure façon (tm) de le faire, mais j'aimerais savoir quelle est la - Angular destiné façon (qui, je pense, devrait produire le moins de code car il peut utiliser le plus par défaut).

MODIFIER:

Je cherche l'image entière . Ce que j'adorerais serait une réponse comme par exemple: "Vous pouvez le faire en utilisant 3 Endpoints [...] en ligne, [...] 2 routes et 2 contrôleurs [...] si vous le faites de cette façon en utilisant que par défaut ... "

21
Scheintod

Il n'y a pas Angular moyen prescrit pour ce que vous demandez. C'est à vous de déterminer le détail de l'implémentation.

En règle générale, j'utilise uniquement deux contrôleurs et modèles par ressource:

  1. ListController
  2. FormController

Le contrôleur de formulaire est utilisé pour les opérations d'édition et de création. Utilisez l'option resolve dans vos définitions d'itinéraire pour transmettre User.get() ou User.new() et un indicateur indiquant s'il s'agit d'une opération d'édition ou de création. Cet indicateur peut ensuite être utilisé dans votre FormController pour décider quelle méthode de sauvegarde appeler. Voici un exemple simple:

.when( '/users', {
  templateUrl: BASE + 'partials/user-list.html',
  controller: 'UserListCtrl' } )
.when( '/user/new', {
  templateUrl: BASE + 'partials/user-form.html',
  resolve: {
    data: ['User', function(User) { return User.new(); }],
    operation: 'create'
  }
  controller: 'UserFormCtrl' } )
.when( '/user/:userId', {
  templateUrl: BASE + 'partials/user-form.html',
  resolve: {
    data: ['User', '$route', function(User, $route) { return User.get($route.current.params.userId); }],
    operation: 'edit'
  }
  controller: 'UserFormCtrl' } )

Et votre contrôleur de formulaire:

app.controller('UserFormCtrl', ['$scope', 'data', 'operation', function($scope, data, operation){
  $scope.data = data;
  $scope.save = function() {
    if (operation === 'edit') {
      // Do you edit save stuff
    } else {
      // Do you create save stuff
    }
  }
}]);

Vous pouvez aller plus loin et créer une liste de base et un contrôleur de formulaire pour déplacer des éléments tels que la gestion des erreurs, les notifications de validation côté serveur, etc. En fait, pour la majorité des opérations CRUD, vous pouvez même déplacer la logique de sauvegarde vers ce contrôleur de base.

21
Beyers

Mes recherches sur une quête similaire m'ont conduit à ce projet "forme-schéma angulaire" https://github.com/Textalk/angular-schema-form .

Pour cette approche ... Vous créez un JSON-Schema qui décrit vos données. Ensuite, augmentez-le avec une autre petite structure JSON qui décrit un "formulaire" (c'est-à-dire affichez des informations spécifiques qui n'appartiennent pas au schéma de données) et il crée une interface utilisateur (formulaire) pour vous.

Un avantage intéressant est que le schéma est également utile pour valider les données (côté client et serveur), c'est donc un bonus.

Vous devez déterminer quels événements devraient déclencher GET/POST/... vers votre API. mais ce serait votre préférence, par exemple. Appuyez sur l'API pour chaque frappe de touche OR le bouton classique [Soumettre] POST retour style OR quelque chose entre les deux avec un enregistrement automatique temporisé.

Pour maintenir cette idée, je pense qu'il est possible d'utiliser StrongLoop pour créer une API rapide, qui (encore) utilise le schéma de vos données (augmenté de certains détails de stockage) pour définir l'API.

pas <3 utilisations de ce schéma, voir [ http://json-schema.org/] qui est au cœur de cette approche.

(lire: pas moins de trois :)

4
Nate-

Vous mélangez peut-être les choses. Les opérations CRUD au niveau de l'API sont effectuées à l'aide de $ resource et celles-ci peuvent ou non correspondre à l'interface utilisateur. Donc, en utilisant $resouce si vous définissez la ressource comme

var r = $resource('/users/:id',null,   {'update': { method:'PUT' }});
r.query()  //does GET on /users and gets all users
r.get({id:1}) // does GET on /users/1 and gets a specific user
r.save(userObject)  // does a POST to /users to save the user
r.update({ id:1 }, userObject) // Not defined by default but does PUT to /users/1 with user object.

Comme vous le voyez, l'API est pleine de ressources mais n'est en aucun cas liée à une vue d'interface utilisateur.

Pour la vue, vous pouvez utiliser la convention que vous avez définie, mais rien de spécifique n'est fourni par Angular.

1
Chandermani