How to use AngularJS $resource custom actions?

前端 未结 2 734
醉酒成梦
醉酒成梦 2020-12-30 10:18

I\'ve been using custom actions in a few repositories. And up until now I only had to specify the url and the method.

For example:

updatePassword: {
         


        
相关标签:
2条回答
  • 2020-12-30 10:54

    When you define a $resource the definition looks like this

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

    The second parameter paramDefaults is just there to provide default values. The @ syntax is used to derive the parameter value from the payload of a PUT or POST request.

    You can always provide parameter values while actually invoking the resource action. If you don't then the default parameter values are taken and if that too are not there then the fragment is removed.

    What can be parameterized needs to be define on $resource using the : syntax and same goes for what the default value is. For the action method they just take the same $http config object.

    0 讨论(0)
  • 2020-12-30 11:00

    The parameters can be declared per custom action.
    The default parameters are what their name implies: default parameters (as in: "used in case other parameters are not provided").

    The use of '@' (either in default parameters or in action parameters) is not mandatory.
    It is provided as a convenience and has a special meaning. paramKey: '@someProp' means:
    "For methods that have a request body (e.g. POST, PUT etc), if I do not explicitly provide a value for the parameter paramKey, please look into my data object for a property named someProp and use its value as the value for the paramKey parameter."


    Note that when you use a class method, you have to explicitly provide the data object:

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

    When you use an instance method, the instance itself acts as the data object:

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

    See, also, this short demo.


    UPDATE:

    It seems like you want to call the following custom action:

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

    Trying to call it like this <ResourceClass>.add({teamId: teamId, technicianId: technicianId}) does not work as expected, as it interpret the (intended to be) params object as a data object.

    From the ngResource documentation, the method signatures for "non-GET" methods (like yours) are:

    • non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
    • non-GET instance actions: instance.$action([parameters], [success], [error])

    From the above exerpt, it is clear that if you only pass one object in "class" action call, then it is interpreted as the data object (the request's payload). Additionally, if you have @-prefixed default parameters, then the URL parameters are going to get resolved against that data object (which is why it worked with default parameters).


    In order for Angular to interpret the params object as a params (and not data object) and since the data param is mandatory, you need to call it like this:

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

    (Alternatively, you could be using a TeamTechnician instance, but that's another story.)

    0 讨论(0)
提交回复
热议问题