加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

通过angularjs为REST api建模关系数据

发布时间:2020-12-17 17:55:49 所属栏目:安全 来源:网络整理
导读:我正在构建一个应用程序,它支持node- mysql组合,以及前端部分的angularjs.后端REST服务已准备就绪,但我正在努力建模我的关系数据.有一些问题,如: $resource relations in Angular.js或 $resource relations in Angular.js [updated].这些方法仍然是最好的方
我正在构建一个应用程序,它支持node- mysql组合,以及前端部分的angularjs.后端REST服务已准备就绪,但我正在努力建模我的关系数据.有一些问题,如: $resource relations in Angular.js或 $resource relations in Angular.js [updated].这些方法仍然是最好的方法,还是资源有任何重大变化?或者也许Restangular是要走的路?

解决方法

这是我的技巧:

我声明了一个名为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,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,id);
                    }
                    else {
                        data.metadata = {operation: operation};
                    }
                    return data;
                });
            });


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

        }]);

1)让我解释一下identityMap(这是this blog post的代码,带有一些扩展功能):

>让我们考虑一个看起来像这样的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

> Resource API非常智能,它使用GET / api / resource1 / 1返回与resources2的resource1关系,以便将使用GET获得的开销保存到resource2,并将一些查询参数保存到resource1_idfk …
>问题是,如果你的应用程序正在对resource1执行GET,然后在某处稍后GET到resource2并编辑resource2,则表示嵌套在resource1中的resource2的对象将不知道该更改(因为它不是相同的Javascript对象参考)
>身份映射解决了此问题,因此您只能对每个资源的实例保留一个引用
>因此,例如,当您在控制器中进行更新时,值会自动更新嵌套此资源的其他对象
>缺点是您必须自己进行内存管理,并在不再需要时刷新身份映射内容.我个人使用Angular Router UI,并在控制器中定义它,该控制器是其他嵌套状态的根:

$scope.$on(“$destroy”,function(){
????modelService.flush();
});
>我在Angular Router UI中使用的另一种方法是,我将要在该控制器中编辑/删除的资源的id作为嵌套状态的参数,并在我使用的嵌套状态中:

$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初始化,但是在我将它混合到对象之后,所以可以在初始化器中引用新函数.另一件我不使用的东西,他为每个资源创建了单个工厂,例如用于扩展逻辑的Proposal和用于操纵实例的其他工厂ProposalSvc.对我而言,你不需要编写很多代码,而且我个人认为Javascript不适合这种面向对象的方法,因此我只返回整个Restangular对象并对其进行操作.

3)我在那里的另一件事是当我的模型中的某些东西用Restangular改变时事件的广播,这是我使用ng-table时所需要的东西.例如,当模型更改并且我的表中的行需要更新以引用更改时,因此在管理表的控制器中,我使用$scope.on(‘eventName’)然后更改相应的行.当您拥有一个多用户实时应用程序并使用websockets进行服务器通知时(这些事件不包含在modelService中),这些事件也很棒.例如,某人删除了数据库中的某些内容,因此服务器通过websocket向所有活着的用户发送有关更改的通知,然后广播与Restangular中使用的相同的事件,并且控制器对其数据执行相同的编辑.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读