Modeling relational data from REST api via angularjs

I am creating an application supported with node-mysql combos, and corner symbols on the outside. The REST backend service is ready, but I'm struggling with modeling my relational data. There are several questions regarding this: the $ resource relationship in Angular.js or the $ resource relationship in Angular. js [updated] . Are these approaches still the best approaches or have there been significant changes in the $ resource? Or maybe relaying is the way to go?

+4
source share
3 answers

Here is my technique:

factory, dataService, Restangular, .

, :

.factory('identityMap',

      var identityMap = {};

      return {
        insert: function(className, object) {
          if (object) {
            var mappedObject;
            if (identityMap[className]) {
              mappedObject = identityMap[className][object.id];
              if (mappedObject) {
                extend(mappedObject, object);
              } else {
                identityMap[className][object.id] = object;
                mappedObject = object;
              }
            } else {
              identityMap[className] = {};
              identityMap[className][object.id] = object;
              mappedObject = object;
            }
            return mappedObject;
          }
        },
        remove: function(className, object) {
          if (identityMap[className] && identityMap[className][id]) delete identityMap[className][id];
        },
        get: function(className, id) {
          return identityMap[className] && identityMap[className][id] ? identityMap[className][id] : null;
        },
        flush: function(){
          identityMap = {};
        }
      };
    }

.factory('modelService', ['Restangular', 'identityMap', '$rootScope', '$log', function(Restangular, identityMap, $rootScope, $log) {
            var ENUM1 = {STATE:0, OTHER_STATE:1, OTHER_STATE2: 2},
                ENUM2 = {OK:0, ERROR:1, UNKNOWN:2};

            function extendModel(obj, modelExtension, modelName){
                angular.extend(obj, modelExtension);
                obj.initExtension();
                obj = identityMap.insert(modelName, obj);        
            }

            function broadcastRestEvent(resourceName, operation, data){
                $rootScope.$broadcast(resourceName + $filter('capitalize')(operation), data);
            }

            var resource1Extension = {
                _extensionFunction1: function() {
                    // ... do something internally ...
                    if (this.something){
                        // this.newValue ....
                        ; 
                    }
                    else {
                        // ....;
                    }
                },
                publicExtensionFunction: function(param1) {
                    // return something
                },
                initExtension: function() {
                    this._extensionFunction2();
                    extendModel(this.resource2, resource2Extension, 'resource2');
                }
            };

            var resorce2Extension = {
                _extensionFunction1: function() {
                    // do something internally
                },
                publicExtensionFunction = function(param1) {
                    // return something
                },
                initExtension: function(){
                    this._extensionFunction1;

                }
            };

            var modelExtensions = {
                'resource1': resource1Extension,
                'resource2': resorce2Extension
            };

            var rest = Restangular.withConfig(function(RestangularConfigurer) {
                RestangularConfigurer.setBaseUrl('/api');

                RestangularConfigurer.setOnElemRestangularized(function(obj, isCollection, what, Restangular){
                    if (!isCollection) {
                        if (modelExtensions.hasOwnProperty(what)) {
                            extendModel(obj, modelExtensions[what], what);
                        }
                        else {
                            identityMap.insert(what, obj);
                        }
                        if (obj.metadata && obj.metadata.operation) {
                            broadcastRestEvent(what, obj.metadata.operation, obj);
                        }
                    }
                    return obj;
                });

                RestangularConfigurer.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
                    var newData;

                    if (operation === 'getList') {
                        newData = data.objects;
                        newData.metadata = {
                            numResults: data.num_results,
                            page: data.page,
                            totalPages: data.total_pages,
                            operation: operation
                        };
                        data = newData;
                    } 
                    else if (operation === 'remove') {
                        var splittedUrl =  url.split('/');
                        var id = splittedUrl.pop();
                        var resource = splittedUrl.pop();  
                        identityMap.remove(resource, id);
                        broadcastRestEvent(resource, operation, id);
                    }
                    else {
                        data.metadata = {operation: operation};
                    }
                    return data;
                });
            });


            return {
                rest: rest,
                enums: {
                    ENUM1: ENUM1,
                    ENUM2: ENUM2
                },
                flush: identityMap.flush,
                get: identityMap.get
            }

        }]);

1) identityMap ( )

  • REST, ( ):

1:

id = Integer
field1 = String
field2 = String
resource2s = [] (List of resources2 which points to this resource with their foreign key)

2:

id = Integer
field1 = String
field2 = String
...
resource1_idfk = Foreign Key to resource 1
  • API , resource1 resources2 GET /api/resource1/1, , GET resource2, resource1_idfk...

  • , GET resource1, - GET - resource2 resource2, , resource2, resource1, ( Javascript)

  • ,

  • , , , ,

  • , , . Angular Router UI , :

    $scope. $on ( "$ destroy", function() {   modelService.flush(); });

  • , Angular, , , / , ,

    $scope.resource1instance = modelService.get('resource1', $stateParams.id);

resource1.put(...).then(
    function(){
        // you don't need to edit resource1 in list of resources1
        $state.go('^');  
    }    
    function(error){
        handleError(error);    
    });

2) , `Restangular setOnElemRestangularized. , , , . , , mixin, , , . , , , factory , , factory ProposalSvc . , , , Javascript - , Restangular .

3) , , - , - Restangular, , , ng-. , , , , , $scope.on('eventName'), . , , websockets ( modelService). , - - , , websocket , , Restangular, .

+5

, , , ngResource, Restangular - $http.

$- , , Restangular .

The ngModules website shows a list of REST API modules for AngularJS.

If you have a simple REST API, go with $ resource for now, and then switch to Restangular if you do a lot of custom encoding and filtering. This is a much more convenient structure and more extensible.

+2
source

All Articles