AngularJS'this'引用$ timeout函数不起作用

时间:2016-02-26 16:33:14

标签: javascript angularjs timeout

我有一个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不是函数”。

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

提前感谢您的帮助

3 个答案:

答案 0 :(得分:10)

您有两个选择:

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关于函数的上下文。

答案 1 :(得分:2)

超时内的函数具有不同的范围,因为它不是属于控制器的函数。在超时之前将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);
}
})

答案 2 :(得分:0)



table['price'] = (table['ex']['availableToBack'][0].get('price') 
                  if table['ex']['availableToBack'] 
                  else None)

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

});