AngularJS service http success function using wron

2020-05-19 03:03发布

问题:

The success function of a $http.put doesn't have access to the this scope of the service it's being called inside. I need to update a property of the service in the call back from the PUT request.

This is a cut down example of what I'm trying to do in a service:

var myApp = angular.module('myApp', function($routeProvider) {
// route provider stuff
}).service('CatalogueService', function($rootScope, $http) {
    // create an array as part of my catalogue
    this.items = [];

    // make a call to get some data for the catalogue
    this.add = function(id) {
        $http.put(
            $rootScope.apiURL,
            {id:id}
        ).success(function(data,status,headers,config) {
             // on success push the data to the catalogue
             // when I try to access "this" - it treats it as the window
             this.items.push(data);
        }).success(function(data,status,headers,config) {
            alert(data);
        });
    }
}

Sorry if there are some errors in the JS, the main point is how do I access the service scope from inside the success callback?

EDIT : while the answer to this question was correct, I switched to the factory method as both Josh and Mark recommended it

回答1:

Create a closure over a variable (often called that) that is assigned to this so that your callback functions will have access to your service object:

app.service('CatalogueService', function($rootScope, $http) {
    var that = this;
    ...
        ).success(function(data,status,headers,config) {
          that.items.push(data);

Here is a Plunker that uses $timeout instead of $http to demonstrate.



回答2:

As far as I know, you can't. But I wouldn't try to run the service that way anyway. Here is a cleaner way:

.factory('CatalogueService', function($rootScope, $http) {
  // We first define a private API for our service.

  // Private vars.
  var items = [];

  // Private methods.
  function add( id ) {
    $http.put( $rootScope.apiURL, {id:id} )
    .success(function(data,status,headers,config) { items.push(data); })
    .then(function(response) { console.log(response.data); });
  }

  function store( obj ) {
    // do stuff
  }

  function remove( obj ) {
    // do stuff
  }

  // We now return a public API for our service.
  return {
    add: add,
    store: store,
    rm: remove
  };
};

This is a very common pattern of developing services in AngularJS and it doesn't require any use of this in these cases.