AngularJS 'this' $timeout 函数中的引用无效
AngularJS 'this' reference in $timeout function not working
我有一个 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 is not a function"。
为什么?我该如何解决这个问题?我很难找到一种方法来绕过需要我的代码像这样 运行 而不向我的控制器添加不必要的逻辑。
提前感谢您的帮助
timeout 中的函数具有不同的作用域,因为它不是属于控制器的函数。在超时之前将 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 个选择:
1) 使用函数对象的bind()
方法:
更改超时回调的上下文,到达控制器this
:
this.runTimeoutExample = function(){
$timeout(function(){
this.doSomething();
}.bind(this), 1000);
}
2) 创建一个特殊变量self
,以保持link到主服务函数上下文:
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 关于函数的上下文。
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>
我有一个 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 is not a function"。
为什么?我该如何解决这个问题?我很难找到一种方法来绕过需要我的代码像这样 运行 而不向我的控制器添加不必要的逻辑。
提前感谢您的帮助
timeout 中的函数具有不同的作用域,因为它不是属于控制器的函数。在超时之前将 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 个选择:
1) 使用函数对象的bind()
方法:
更改超时回调的上下文,到达控制器this
:
this.runTimeoutExample = function(){
$timeout(function(){
this.doSomething();
}.bind(this), 1000);
}
2) 创建一个特殊变量self
,以保持link到主服务函数上下文:
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 关于函数的上下文。
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>