web-dev-qa-db-fra.com

AngularJS: Création d'objets mappés à REST Ressources (style ORM)

Je suis assez nouveau dans AngularJS, mais je ne sais pas trop comment le lier au backend de mon serveur REST Api.

Par exemple, supposons que j'ai une ressource "image" obtenue en obtenant GET-ing: myApi/image/1 /. Ceci retourne un objet JSON avec divers champs. Disons quelque chose comme:

{url: "some/url", date_created: 1235845}

Maintenant, je veux une sorte de représentation dans mon application AngularJS de cet objet "Image". Cette représentation est plus qu’un mappage des champs - je souhaite ajouter des fonctions "helper", par exemple une fonction qui convertit le date_create champ en quelque chose de lisible par l'homme.

Je connais le service $ resource, mais je ne sais pas exactement ce que je dois faire pour créer une "classe" de base dans Angular, qui utilise Resource pour obtenir l'objet JSON, mais l'améliore ensuite en ajoutant diverses fonctions d'assistance.

Points bonus:

Je ne sais pas non plus comment ajouter des "relations" entre les modèles. Par exemple, une ressource "utilisateur" peut contenir une ressource "image" et je souhaite saisir la ressource Utilisateur, mais je peux également appeler des fonctions d'assistance "Image" dans la partie "Image" de le modèle.

64
Edan Maor

JSData
Un projet qui a débuté sous le nom angular-data est maintenant "un magasin de données indépendant de la structure, conçu pour une utilisation aisée et une tranquillité d'esprit". Il possède une excellente documentation et prend en charge les relations, les backends multiples (http, localStorage, firebase), la validation et bien sûr angular).
http://www.js-data.io/

BreezeJS
Le chaîne YouTube AngularJS contient ceci la vidéo utilise BreezeJS

C'est un ORM avancé qui prend même en charge le filtrage côté client et d'autres fonctionnalités intéressantes. Il convient mieux au backend supportant OData , mais peut fonctionner avec d’autres types de backends.

ngResource
Une autre option consiste à utiliser ngResource , voici un exemple sur la façon de l’étendre avec vos propres fonctions:

module.factory('Task', function ($resource) {
    var Task = $resource(WEBROOT + 'api/tasks/:id', {id: '@id'}, {update: { method: 'PUT'}});
    angular.extend(Task.prototype, {

        anExampleMethod: function () {
            return 4;
        },

        /**
         * Backbone-style save() that inserts or updated the record based on the presence of an id.
         */
        save: function (values) {
            if (values) {
                angular.extend(this, values);
            }
            if (this.id) {
                return this.$update();
            }
            return this.$save();
        }
    });
    return Task;
});

J'ai trouvé que ngResource était très limité, même comparé à Backbone.Model qui a:

  • Analyse JSON personnalisée via Model.parse
  • Possibilité d'étendre un modèle de base (pas de baseUrl dans ngResource)
  • D'autres crochets comme Backbone.sync, qui active LocalStorage, etc.

Restangular
"Le service AngularJS permet de gérer correctement et facilement les ressources de repos de l'API Rest"
http://ngmodules.org/modules/restangular

Ou essayez quelques-uns des autres ORM
Quelles options sont disponibles pour ORM JavaScript côté client?

80
Bob Fanger

Je suis le créateur de Restangular, mon opinion peut donc être biaisée.

Mais comme l'a dit Bob, vous pouvez utiliser Restangular pour cela.

Restangular utilise vos ressources d'API Restful pour parcourir l'arborescence. Vous pouvez également ajouter de nouvelles méthodes à cela.

Voici un exemple de code: https://github.com/mgonto/restangular#lets-code

Et de cette façon, vous pouvez ajouter de nouvelles méthodes à votre objet (Les points bonus :)) https://github.com/mgonto/restangular#creating-new-restangular-methods

J'espère que cela te convient :).

Sinon, vous pouvez aussi utiliser ngResource ($ resource) pour cela, mais à mon avis, il faut un peu "d'amour" et de "sucre".

Meilleurs

15
mgonto

Pour une interaction simple, vous pouvez utiliser Angular-Resource ( http://docs.angularjs.org/api/ngResource . $ Resource), ce qui peut s'avérer très pratique pour simple REST = interaction (pour le télécharger, allez à http://code.angularjs.org/1.0.6/ )

Malheureusement, vous n’exercez qu’un contrôle limité lors de l’utilisation de la ressource angular); vous devrez créer vos propres services sur la base du service Angularjs $ http - http: // docs. angularjs.org/api/ng .$http.

J'espère que ça t'as aidé.

7
Guy Nesher

Après de nombreuses recherches, voici une liste complète de toutes les solutions disponibles:

mais honnêtement, je n'étais pas très heureux, j'ai donc décidé d'ajouter à la liste ma propre solution, haha. Découvrez-le ici: $ modelFactory .

Votre code de résultat final finit par ressembler à quelque chose comme:

var module = angular.module('services.Zoo', ['modelFactory']);

module.factory('AnimalModel', function($modelFactory){
  return $modelFactory('api/Zoo');
});

return module;

Je pense que c'est une meilleure solution par rapport au reste car principalement la définition du modèle ressemble de près à celle de ngResource d'Angular, ajoutant seulement des fonctionnalités de bas niveau dont il manque. Son poids super léger (1,45k gzip/min) et n’a que quelques petites dépendances (pas de lodash, jquery, etc.).

5
amcdnl

ModelCore ( https://github.com/klederson/ModelCore ) fonctionne à peu près comme ceci et est très très facile à mettre en œuvre:

var ExampleApp = angular.module('ExampleApp', ['ModelCore']); //injecting ModelCore

ExampleApp.factory("Users",function(ModelCore) {
  return ModelCore.instance({
    $type : "Users", //Define the Object type
    $pkField : "idUser", //Define the Object primary key
    $settings : {
      urls : {
        base : "http://myapi.com/users/:idUser",
      }
    },
    $myCustomMethod : function(info) { //yes you can create and apply your own custom methods
        console.log(info);
    }
  });
});

//Controller
function MainCrtl($scope, Users) {
  //Setup a model to example a $find() call
  $scope.AllUsers = new Users();

  //Get All Users from the API
  $scope.AllUsers.$find();

  //Setup a model to example a $get(id) call
  $scope.OneUser = new Users();

  //Hey look there are promisses =)
  //Get the user with idUser 1 - look at $pkField
  $scope.OneUser.$get(1).success(function() {
    console.log("Done!",$scope.OneUser.$fetch());
});
4
Klederson Bueno

Angular Rest-Mod est une autre bonne option pour les modèles à base angulaire/ORM.

Restmod crée des objets que vous pouvez utiliser depuis l’intérieur de Angular pour interagir avec votre API RESTful. Il prend également en charge les collections, les relations, les hooks de cycle de vie, le changement de nom d’attributs, etc.

3
amcdnl

Encore un exemple d’assistance pour ngResource. Cela repose sur le fait que la grande majorité des services ressemble à ceci:

http://Host/api/posts
http://Host/api/posts/123
http://Host/api/posts/123/comments
http://Host/api/posts/123/comments/456

La tâche consiste donc à créer un assistant qui crée des objets de ressources AngularJS mappés sur de tels services. C'est ici:

'use strict';

var api = angular.module('api', ['ngResource']);

// RESTful API helper
api.addService = function (serviceNameComponents) {
    var serviceName = "";
    var resource = "/api"; // Root for REST services
    var params = {};

    serviceNameComponents.forEach(function (serviceNameComponent) {
        serviceName += serviceNameComponent;

        var lowerCaseServiceNameComponent = serviceNameComponent.toLowerCase();
        var collection = lowerCaseServiceNameComponent + 's';
        var id = lowerCaseServiceNameComponent + 'Id';

        resource += "/" + collection + "/:" + id;
        params[id] = '@' + id;
    });

    this.factory(serviceName, ['$resource',
        function ($resource) {
            return $resource(resource, {}, {
                    query: {
                        method: 'GET',
                        params: params,
                        isArray: true
                    },
                    save: {
                        method: 'POST',
                    },
                    update: {
                        method: 'PUT',
                        params: params,
                    },
                    remove: {
                        method: 'DELETE',
                        params: params,
                    }
                }
            );
        }
    ]);
}

Donc, pour l'utiliser, appelez simplement cette aide

api.addService(["Post"]);
api.addService(["Post", "Comment"]);

Et ensuite, vous pouvez utiliser Post et PostComment dans le code avec les paramètres nécessaires tels que: post_id

2
Denis