【问题标题】:AngularJS 'this' reference in $timeout function not working$timeout 函数中的 AngularJS 'this' 引用不起作用
【发布时间】:2016-06-09 23:30:52
【问题描述】:

我有一个 AngularJS 问题让我非常抓狂。我有一个看起来像这样的服务(这是一个说明问题的示例)

var app = angular.module('test-module');

app.service('ToolService', function($timeout){

    this.doSomething = function() {
       console.log("y u no referenced as method?!?");
    }

    this.runTimeoutExample = function(){
        $timeout(function(){
            this.doSomething();
        }, 1000);
    }
})

我的控制器如下所示:

var app = angular.module('test-module', []);

var ctrl = app.controller('main-controller', function($scope, ToolService) {

    $scope.somethingWasClicked = function() {
        ToolService.runTimeoutExample();
    }

});

这是问题所在,当单击调用 $scope.somethingWasClicked 的按钮时,它会将调用转发给服务,并且我收到一条错误消息,提示“this.doSomething 不是函数”。

为什么?我该如何解决这个问题?我很难找到一种方法来绕过需要我的代码像这样运行而不向我的控制器添加不必要的逻辑。

提前感谢您的帮助

【问题讨论】:

标签: javascript angularjs timeout


【解决方案1】:

var app = angular.module('test-module',[]);

app.service('ToolService', function($timeout){

   function doSomething() {
       console.log("y u no referenced as method?!?");
    }

    this.runTimeoutExample = function(){
        $timeout(function(){
           doSomething();
        }, 1000);
    }
});
 app.controller('main-controller', function($scope, ToolService) {
   
    $scope.somethingWasClicked = function() {
    
        ToolService.runTimeoutExample();
    };

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test-module" ng-controller="main-controller">
  
  <input type="button" value="click" ng-click="somethingWasClicked()">
  
  </div>

【讨论】:

    【解决方案2】:

    你有两个选择:

    1) 使用函数对象的bind()方法:

    改变超时回调的上下文,到达控制器this

    this.runTimeoutExample = function(){
        $timeout(function(){
            this.doSomething();
        }.bind(this), 1000);
    }
    

    2) 创建一个特殊变量self,以保持与主服务函数上下文的链接:

    var app = angular.module('test-module');
    
    app.service('ToolService', function($timeout){
        var self = this;     
        self.doSomething = function() {
           console.log("y u no referenced as method?!?");
        }
    
        self.runTimeoutExample = function(){
            $timeout(function(){
                self.doSomething();
            }, 1000);
        }
    })
    

    如果每次都使用self,你肯定不会发生上下文丢失的情况。

    Read more 关于函数的上下文。

    【讨论】:

    • 这对我也有用,感谢您的快速响应!
    • @the_camino 很高兴为您提供帮助。
    • 我使用了 bind 方法,因为在我的真实代码中实际上在超时之上还有一层上下文,并且绑定似乎是一种更简洁的方式来传递引用
    • @the_camino 听起来是个不错的解决方案。 bind()的问题是每次都写的必要性:)。
    【解决方案3】:

    超时内的函数具有不同的范围,因为它不是属于控制器的函数。在超时之前将this 分配给一个变量,然后使用该变量:

    var app = angular.module('test-module');
    
    app.service('ToolService', function($timeout){
    
    this.doSomething = function() {
       console.log("y u no referenced as method?!?");
    }
    
    this.runTimeoutExample = function(){
        var self = this;
        $timeout(function(){
            self.doSomething();
        }, 1000);
    }
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2020-06-04
      • 2018-12-24
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多