2014-09-19 51 views
8

我一直在一些存儲庫中使用自定義操作。直到現在,我只需要指定url和方法。

例如:

updatePassword: { 
    url: ENV.NITRO_PROJECT_REST_URL + '/admins/:adminId/password', 
    method: 'PUT' 
} 

但後來,我不得不代碼有,不是一個自定義操作,但有兩個路徑參數:

technicianModule.controller('technician.teamCtrl', 
    ['$scope', '$state', '$stateParams', 'CommonService', 'TechnicianService', 'TeamService', 'TeamTechnicianService', 
    function($scope, $state, $stateParams, CommonService, TechnicianService, TeamService, TeamTechnicianService) { 

    $scope.add = function(teamId) { 
     TeamTechnicianService.add(teamId, $stateParams.technicianId, function() { 
     TeamService.get(teamId, function(data) { 
      $scope.teams.push(data); 
      $scope.unassignedTeams.splice(CommonService.getResourceIndex($scope.unassignedTeams, data), 1); 
     }); 
     }); 
    }; 

    } 
]); 

teamModule.factory('TeamTechnicianService', 
    ['RESTService', 
    function(RESTService) { 
    var factory = {}; 

    factory.add = function(teamId, technicianId, callback) { 
     return RESTService.TeamTechnician.add({teamId: teamId, technicianId: technicianId}).$promise.then(callback); 
    } 

    return factory; 
    } 
]); 

所以我第一編碼它想:

TeamTechnician: $resource(ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamtechnicianId', {}, { 
add: { 
    url: ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamId/:technicianId', 
    method: 'POST' 
} 

但它不會工作。參數未被傳入。

經過幾次嘗試後,我發現它在添加一些參數定義時工作正好在自定義動作定義之前。

它必須是這樣的:

TeamTechnician: $resource(ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamtechnicianId', { 
    teamId: '@teamId', 
    technicianId: '@technicianId' 
}, { 
add: { 
    url: ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamId/:technicianId', 
    method: 'POST' 
} 

注意的存在:

teamId: '@teamId', 
technicianId: '@technicianId' 

我的理解是那麼在$資源定義,有多個路徑參數自定義操作,要求用@符號來定義它們。

而不是當它只有一個。

這是爲什麼?

爲什麼不能在自定義操作中聲明路徑參數,而不是在資源上面聲明?

回答

23

參數可以根據自定義操作進行聲明。
默認參數是它們名字的含義:默認參數(如:「用於未提供其他參數的情況下」)。

採用'@'(無論是在默認參數或在動作參數)是強制性的。
它作爲一種便利提供並具有特殊的含義。paramKey: '@someProp'表示:
「對於具有請求體(例如POST,PUT等)的方法,如果我沒有明確提供參數paramKey的值,請查看我的數據對象以獲取名爲someProp的屬性並使用其值作爲paramKey參數的值。「


注意,當你使用一個類的方法,你必須明確提供的數據對象:

SomeResourceClass.save({.../* data object */...}); 

當您使用實例方法,該實例本身充當數據對象:

var instance = SomeResourceClass.get(...); 
instance.$save(); /* `instance` will act as the data object. */ 

還參見本short demo


UPDATE:

好像你要撥打以下自定義操作:

add: { 
    url: ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamId/:technicianId', 
    method: 'POST' 
} 

試圖調用它<ResourceClass>.add({teamId: teamId, technicianId: technicianId})沒有按預期工作,因爲它解釋將(作爲)params對象作爲數據對象。

ngResource文檔中, 「非GET」 方法的方法簽名(像您)是:

  • 非GET 「類」 動作:Resource.action([參數],POSTDATA,[成功],[錯誤])
  • 非GET實例動作:例如$行動([參數],[成功],[錯誤])

從上面exerpt,很顯然,如果你只在「類」動作調用中傳遞一個對象,則將其解釋爲ob data ob ject(請求的有效載荷)。此外,如果您有@-前綴默認參數,則URL參數將針對該對象(這是爲什麼它使用默認參數)得到解決。


爲了角度解釋params對象作爲params(而不是data對象),並自data參數是強制性的,你需要調用它像這樣:

<ResourceClass>.add({teamId: teamId, technicianId: technicianId}, {}) 

(或者,你可以使用一個​​實例,但這是另一回事。)

+5

您對默認參數的解釋不僅僅是官方文檔。 – Stephane 2014-09-19 14:26:40

+0

好的,每個自定義動作都可以聲明參數。但爲什麼我需要參數用於我的POST而不是我的PUT點? – Stephane 2014-09-19 14:28:20

+0

@StephaneEybert:POST和PUT方法的處理方式相同,所以不應有任何區別。你可以提供一個小提琴或至少一個** [SSCCE](http://sscce.org)**,以便我可以重現你面臨的問題? (順便說一下,如果這個答案幫助你不忘記上傳和/或接受它) – gkalpak 2014-09-19 18:51:30

3

當你定義一個$資源的定義是這樣的

$resource(url, [paramDefaults], [actions]);

第二個參數paramDefaults只是在那裏提供默認值。 @語法用於從PUT或POST請求的有效內容中派生參數值。

您可以始終在實際調用資源操作時提供參數值。如果你不這樣做,默認的參數值將被採用,如果那樣也不存在,那麼該片段將被刪除。

需要使用:語法在$ resource上定義什麼參數化,其缺省值也是如此。 對於操作方法,他們只是採用相同的$http config對象。

+0

謝謝,但我的原始問題是爲什麼我的PUT自定義操作不會n不需要任何路徑參數,我的POST自定義操作需要它們。 – Stephane 2014-09-19 14:30:39

+0

這就是你如何調用方法和傳遞參數。如果參數未通過,則傳遞paramDefaults的默認值。 – Chandermani 2014-09-19 15:28:46

+0

我不需要默認值。我傳遞參數。只有這些沒有被看到。我原來的問題代表。 – Stephane 2014-09-19 17:12:13