【问题标题】:AngularJS service http success function using wrong "this" scopeAngularJS服务http成功函数使用错误的“this”范围
【发布时间】:2013-02-18 06:31:28
【问题描述】:

$http.put 的成功函数无权访问它在内部调用的服务的this 范围。我需要在 PUT 请求的回调中更新服务的属性。

这是我在服务中尝试做的一个简化示例:

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

如果JS有错误,很抱歉,主要是如何从成功回调内部访问服务范围?

编辑:虽然这个问题的答案是正确的,但我改用了 factory 方法,因为 Josh 和 Mark 都推荐了它

【问题讨论】:

    标签: http service angularjs


    【解决方案1】:

    据我所知,你不能。但无论如何我都不会尝试以这种方式运行服务。这是一种更清洁的方法:

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

    这是在 AngularJS 中开发服务的一种非常常见的模式,在这些情况下它不需要使用任何this

    【讨论】:

    • 我试图了解服务和工厂之间的区别,但我认为工厂应该return 自己,而服务不是:stackoverflow.com/questions/13762228/…
    • 当我复制粘贴你的代码时,我忘了把它改成.factory。我更新了答案。服务是使用几种模块方法之一创建的。 factory 返回你想要的任何东西,service 只接受一个由提供者运行的构造函数,它返回新对象。无需借助一些 JavaScript 魔法,您将希望使用 factory 来存储异步操作的结果。
    • 好的,所以我已经解决了items 的问题,方法是按照你上面概述的方法,但是现在我在尝试从工厂调用不同的方法时遇到了同样的问题成功回调。我正在下载一些数据,如果下载成功,我想调用store() 方法将其写入localStorage。在您的代码示例中,它就像调用 get() 方法一样。
    • 您需要返回私有实现的公共 API。那么你永远不必打电话给this。我更新了答案。
    • 如果您在返回对象中公开标量变量或数组,@JoshDavidMiller 会起作用吗?我注意到你只返回了函数。
    【解决方案2】:

    在分配给this 的变量(通常称为that)上创建一个闭包,以便您的回调函数可以访问您的服务对象:

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

    这是一个Plunker,它使用$timeout而不是$http来演示。

    【讨论】:

    • 在这种情况下,我仍然更喜欢工厂方法,但 +1 表示实际回答问题。 :-)
    • @Josh,我也喜欢工厂。
    • 我将使用工厂答案,但我觉得我应该选择这个作为正确答案,因为它回答了这个问题。我肯定会在我的问题中添加一个编辑,以提及我已经求助于您的问题@JoshDavidMiller
    • @Skeater 这完全公平。正如我所说,马克确实回答了这个问题,我回避了。 :-)
    猜你喜欢
    • 2012-09-23
    • 2014-02-14
    • 2014-09-22
    • 2013-06-19
    • 2015-12-07
    • 2015-03-16
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多