2013-04-24 72 views
64

對於AngularJS我很新,但我很不清楚如何將它綁定到我的服務器的REST Api後端。AngularJS:創建映射到REST資源的對象(ORM樣式)

例如,假設我有一個通過GET-ing獲取的「圖像」資源:myApi/image/1 /。這將返回一個帶有各種字段的json對象。讓我們這樣說:

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

現在,我想在我的AngularJS這個「圖像」對象的應用某種代表性。這種表示不僅僅是字段的映射 - 我想添加「幫助」功能,例如將date_create字段轉換爲人類可讀的字段的功能。

我知道$ resource服務,但我不清楚我需要在Angular中創建一個基本的「類」,它使用Resource獲取JSON對象,但通過添加各種幫助函數。

加分點:

我也不清楚如何添加模型之間的「關係」。例如,我可能有一個「用戶」資源,其中嵌入了一個「圖像」資源,我想獲取用戶資源,但能夠在「圖像」部分調用「圖像」輔助函數該模型。

+0

這聽起來像你想要某種角度支持的模型框架。據我所知,在內置的角度上沒有這樣的東西。 – thalador 2013-04-24 09:21:18

+3

@thalador - 我正在尋找甚至只是聽到最好的做法,如何去建立自己的。我應該用一個服務包裝一個「資源」對象並添加方法嗎?用一個單獨的服務包裝一個「資源」對象?等等。 – 2013-04-24 12:20:42

回答

80

JSData
它開始作爲角數據的一個項目現在是「爲易用性和安心了一個框架,無關的數據存儲。」 它具有優秀的文檔,並支持關係,多個後端(http,localStorage,firebase),驗證和角度整合。
http://www.js-data.io/

BreezeJS
AngularJS YouTube channel特徵this視頻使用BreezeJS

哪個是一種先進的ORM甚至支持客戶端過濾等涼的東西。 它最適合支持OData的後端,但可以用於其他類型的後端。

ngResource
另一種選擇是使用ngResource,這裏是如何將它與自己的功能擴展的例子:

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

我發現ngResource是非常有限的,甚至比骨幹。其具有型號

  • 定製JSON經由Model.parse解析
  • 能夠延長一個BaseModel(否的baseUrl在ngResource)
  • 其他鉤等Backbone.sync,這使得能夠本地存儲,等等

Restangular
「AngularJS服務適當且容易地處理REST API RESTful資源」
http://ngmodules.org/modules/restangular

或嘗試一些其他的ORM的
What options are available for client-side JavaScript ORM?

+1

微風很可能是您的正確選擇(免責聲明:我是Breeze維護人員之一)。要清楚,Breeze是一個純粹的JavaScript庫。它不是一個ORM。它不關心OData。它可以很好地與ORM,OData和其他.NET技術一起使用,這是我們通常演示它的方式。但是,您可以使用* any技術編寫幾乎任何* HTTP服務(包括REST服務),如[Breeze Edmunds示例](http://www.breezejs.com/samples/edmunds)所示。如果您有微風問題,請在SO上提問,標記爲「微風」,我們會找到它。 – Ward 2013-05-01 02:45:50

+0

我認爲Breeze是一個正確的長期選擇,而且我們一定會考慮下一個項目。對於這一個,我們將繼續使用ngResource和自定義函數。 – 2013-05-04 09:03:01

15

我Restangular的創造者,所以我的意見能被偏置。

但正如鮑勃所說,你可以使用它的Restangular。

Restangular使用您的Restful API資源來檢查樹。你也可以爲此添加新的方法。

這是編碼例:https://github.com/mgonto/restangular#lets-code

而這種方式,您可以添加新的方法,以你的對象(獎勵積分:))https://github.com/mgonto/restangular#creating-new-restangular-methods

希望這個作品爲你:)。

否則,你也可以使用ngResource($ resource),但在我看來,它需要一些「愛」和「糖」。

最好成績

4

ModelCore(https://github.com/klederson/ModelCore)的作品非常喜歡這一點,是非常非常容易實現:幫手ngResource的

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

再舉一個例子。這依賴於事實是,絕大多數的服務是類似的東西:

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

所以,任務是使創建這樣的服務映射AngularJS資源對象的輔助工具。那就是:

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

所以,用它簡單地調用這個輔助

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

然後你就可以在代碼中包含所需的PARAMS使用郵政和PostComment:POST_ID

3

Angular Rest-Mod是另一個基於角度的模型/ ORM的良好選擇。

Restmod創建可以在Angular中使用的對象,與您的RESTful API進行交互。它還支持集合,關係,生命週期鉤子,屬性重命名等等。

+0

你能否添加一些例子? – blackjid 2014-08-18 14:11:50

5

經過大量的研究,這裏是所有的解決方案提供一個全面的列表:

,但說實話我不是很開心,所以我決定添加到我自己的解決方案哈哈。看看這裏:​​。

您的最終結果代碼最終看起來像:

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

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

return module; 

我相信這是在休息一個更好的解決方案,因爲主要是模型定義非常類似於角的ngResource,加入只是低層次的功能之一的需求它缺乏。它的超級輕量級​​(1.45k gzip/min),並且只有一些小的依賴關係(無lodash,jquery等)。