2014-12-02 73 views
0

所以我用這個REST API與ngResource做得到查詢更新請求。我正在尋找的是一種爲每個實體定義結構的方法。角資源 - 默認的模型結構

例如,假設我們有:

module.factory('app.entity.item', function($resource) { 
    return $resource('http://xmpl.io/items/:itemId', { itemId: '@id' }); 
}); 

我想它實例化一個控制器,如:

module.controller('AddItemCtrl', ['app.entity.item', function(Item) { 
    $scope.item = new Item(); 
}); 

並將其綁定到模板中的相應表格。

我遇到的實際問題是我必須處理1:m表格。 的實體結構的例子是:

{ 
    "name": "", 
    "categories": [], 

    "list": [ 
    { 
     "value": "", 
     "list": [ 
     { 
      "value": "", 
      "list": [ 
      { 
       "value": "" 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

(在下面的撥弄更透徹的例子)

現在前兩個字段顯然不是問題。這是第三個。 list。這些列表中的每一個都可以包含可變數量的項目。

我目前使用ngRepeat和add(type, context)方法,增加了一個新的字段集的範圍(value場在這個例子中和孩子列出了前兩個級別),這將是ngRepeat出現在用戶界面,使用戶可以填寫並提交給服務。

首先,我必須定義結構,因此在頁面加載時UI不會爲空。

module.controller('AddItemCtrl', ['app.entity.item', function(Item) { 
    $scope.item = new Item({ 
     "name": "", 
     "categories": [], 

     "list": [ 
     { 
      "value": "", 
      "list": [ 
      { 
       "value": "", 
       "list": [ 
       { 
        "value": "" 
       } 
       ] 
      } 
      ] 
     } 
     ] 
    }); 
}); 

但這是多餘的。我必須到處去做! 另一個問題是調用item.$save時,模型被清空(可能重新實例化?),並且列表屬性(由ngRepeat指令管理)中的字段消失了。

所以我想知道,你會在這種情況下做什麼。 有沒有辦法來定義實體(資源)結構?

示例:http://jsfiddle.net/g15sqd5s/3/

回答

1

試圖給答案很簡單 - 簡單的結構,我會使用類似

module.factory('Item', function($resource) { 
    var resource = $resource('http://xmpl.io/items/:itemId', { itemId: '@id' }, 
    // you can also define transformRequest here: 
    { transformRequest: function(data) { 
     // data can be transformed here 
     return angular.toJson(data); 
    }}); 

    return angular.extend(resource.prototype, 
    { 
     name: null, 
     categories: [] 
    }); 
    }); 

但後來意識到需要對'flatten' the object

,併爲更復雜的模型我會檢查restangular

類似的話題也在這裏討論: How can I extend the constructor of an AngularJS resource ($resource)?

+0

我沒有看到transformRequest被用於什麼;我不確定操縱原型,但它肯定是一個解決方案。 +1和參考。 – Fardin 2015-02-18 09:21:27

+0

transformRequest只是表明還有另一個機會來處理複雜/非標準的案例。 – ciekawy 2015-02-18 10:41:01

+0

啊哈!我意識到這一點,但我認爲這不能解決我的問題。 – Fardin 2015-02-18 13:52:25

0

我會繼續前進,在第一個地方後臺修改我的模型結構 - 模型在客戶端應該僅僅遵循已經定義的那些,而不是在變換塊中重新定義。所以,要回答你的問題,「默認」模型結構來自服務器。你在$resource對象中得到的結果是你的服務器返回的結構。

首先,當用戶填充一些值時,確實可以在Item模型上調用$save?我們想要保存的顯然是與物品相關的列表,而不是物品本身。在後端定義的單獨資源,如items/<item_id>/list,可能是更清晰的解決方案。它可能無法很好地擴展,因爲您必須爲每個項目提供單獨的GET請求以獲取其列表,但這是正確的RESTful方式。

將此方法擴展到您的小提琴示例中,我想象一個路由方案,如buildings/<building_id>/floors/<floor_id>/units/<unit_id>將是一個適當的解決方案。向buildings/發出GET請求會產生一個建築物列表;返回數組中的每個建築物應該是Building模型的實例,該模型具有正確的URL設置,因此用戶可以執行單個POST並僅更新建築物名稱,而不是將整個結構發送回服務器。遞歸地應用嵌套資源應該給你一個乾淨而簡潔的方式來處理模型變化。

關於UI部分 - 我將繼續爲建築物,樓層和單元定義三條指令,並讓每個指令都使用各自的資源管理數組,並考慮UI綁定到模型值。

那麼Building模型怎麼樣?

var BuildingResource = $resource('/buildings/:id', { id: '@id' }); 

調用BuildingResource.query()應產生現有建築物的陣列。添加一個新的建築看起來是這樣的:

var newBuilding = new BuildingResource(); 
newBuilding.$save().then(function(building) { 
    $scope.buildings.push(building); 
}, function(errData) { 
    //Handle error here... 
}); 

應該很容易擴展這種模式對於資源的其餘部分 - 注意,所謂的服務器需要返回的每一個建築只是nameid;知道id就足以構建一個URL(和一個$resource對象)來獲取所需的子資源(在本例中爲floor)。

+0

模型不在重定義。我正在向用戶提供一個表單來創建一個不存在的實體。我不相信我應該問服務器一個空的模型!你所說的「適當的RESTful方法來做到這一點」在我的jsfiddle例子中是完全正確的;但我們正在與一個單一的實體合作;另外,我們正在儘量減少請求。歡迎BTW。 – Fardin 2015-02-23 13:52:37

+0

在我的示例中沒有單點要求服務器提供空模型。第二個代碼片段在客戶端創建一個模型,該模型可能包含任何需要的數據(例如名稱)。 'POST'請求的響應然後被添加到範圍數組中 - 它將包含從數據庫返回的有效標識。如果您正在使用單個實體,那麼原始查詢中'1:m'是什麼意思?這意味着,在單個「基礎」實體的頂部,您將擁有一組實體。這正是所提出的方法所要處理的。 – 2015-02-23 14:33:35

+0

我的角度應用程序不關心服務器處理模型的方式;它只能看到一個實體。 (假設在這種情況下它是很有意義的!)我提到1:m讓讀者能夠可視化結構。那是在我添加例子之前。 ---所提出的方法不能解決所提出的問題。我想生成一個表單。我沒有看到如何拆分原始實體以包含其他實體的層次結構來幫助解決該問題。 – Fardin 2015-02-23 14:44:21