AngularJS: Creating Objects that map to REST Resources (ORM-Style)

前端 未结 7 561
南笙
南笙 2021-01-29 18:09

I\'m pretty new to AngularJS, but I\'m pretty unclear on how to tie it up to my Server\'s REST Api backend.

For example, say I have an \"image\" resource that I get by G

相关标签:
7条回答
  • 2021-01-29 18:26

    One more example of helper for ngResource. This relies on fact that the vast majority of services is something like that:

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

    So, the task is to make a helper that create AngularJS resource objects that maps on such services. Here it is:

    '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,
                        }
                    }
                );
            }
        ]);
    }
    

    So, to use it simply call this helper

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

    And then you can use Post and PostComment in code with needed params like :post_id

    0 讨论(0)
  • 2021-01-29 18:31

    For simple interaction you can use Angular-Resource (http://docs.angularjs.org/api/ngResource.$resource) which can be quite handy for simple REST interaction (to download it go to http://code.angularjs.org/1.0.6/)

    Sadly you only get limited control when using angular resource, and for anything more advanced you will need to create your own services based on Angularjs $http service - http://docs.angularjs.org/api/ng.$http.

    Hope that helps.

    0 讨论(0)
  • 2021-01-29 18:36

    After lots of research, here is a comprehensive list of all the solutions available:

    • Restmod

    • Modelizer

    • ModelCore

    • angular-watch-resource

    • angular-restful

    • ngResource

    • angularjs-rails-resource

    • angular-nested-resource

    • Aar.js

    • Angular Activerecord

    • Angular-Data

    • ngActiveResource

    • restangular

    • BreezeJS

    • ng-backbone

    but honestly I wasn't very happy, so I decided to add to the list my own solution haha. Check it out here: $modelFactory.

    Your end-result code ends up looking something like:

    var module = angular.module('services.zoo', ['modelFactory']);
    
    module.factory('AnimalModel', function($modelFactory){
      return $modelFactory('api/zoo');
    });
    
    return module;
    

    I believe this is a better solution over the rest because mainly the model definition closely resembles Angular's ngResource, adding just low-level features one needs that it lacks. Its super lightweight (1.45k gzip/min) and has only a few small dependencies ( no lodash, jquery, etc ).

    0 讨论(0)
  • 2021-01-29 18:37

    I'm creator of Restangular so my opinion can be biased.

    But as Bob said, you can use Restangular for it.

    Restangular uses your Restful API Resources to go over the tree. You can also add new methods to this.

    This is coding example: https://github.com/mgonto/restangular#lets-code

    And this way you can add new methods to your object (The bonus points :)) https://github.com/mgonto/restangular#creating-new-restangular-methods

    Hope this works out for you :).

    Otherwise, you can also use ngResource ($resource) for this but in my opinion, it needs some "love" and "sugar".

    Bests

    0 讨论(0)
  • 2021-01-29 18:40

    ModelCore ( https://github.com/klederson/ModelCore ) works pretty much like this, and is very very easy to implement:

    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());
    });
    
    0 讨论(0)
  • 2021-01-29 18:46

    JSData
    A project which started as angular-data is now "a framework-agnostic data store built for ease of use and peace of mind." It is has excellent documentation and has support for relations, multiple backends (http, localStorage, firebase), validation and of course angular integration.
    http://www.js-data.io/

    BreezeJS
    The AngularJS YouTube channel features this video using BreezeJS

    Which is an advanced ORM which even supports client-side filtering and other cool stuff. It best suited for backend that support OData, but can be made to work on other types of backends.

    ngResource
    Another option is to use the ngResource, here is an example on how to extend it with your own functions:

    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;
    });
    

    I found ngResource to be very limited, even compared to Backbone.Model which has:

    • Custom JSON parsing via Model.parse
    • Possible to extend a BaseModel (No the baseUrl in ngResource)
    • Other hooks like Backbone.sync, which enables LocalStorage, etc.

    Restangular
    "AngularJS service to handle Rest API Restful Resources properly and easily"
    https://github.com/mgonto/restangular

    Or try some of the other ORM's
    https://stackoverflow.com/questions/6786307/which-javascript-orm-to-use

    0 讨论(0)
提交回复
热议问题