Javascript 为什么是';这';参考';窗口';在这个类型脚本片段中?
鉴于此件代码:Javascript 为什么是';这';参考';窗口';在这个类型脚本片段中?,javascript,angularjs,typescript,Javascript,Angularjs,Typescript,鉴于此件代码: module movieApp { export interface IHomeControllerScope extends ng.IScope { moviesToDownload: string[]; active: string; deleteMovieFromDownloadList(movie: any); markMovieAsDownloaded(movie: any); }
module movieApp {
export interface IHomeControllerScope extends ng.IScope {
moviesToDownload: string[];
active: string;
deleteMovieFromDownloadList(movie: any);
markMovieAsDownloaded(movie: any);
}
export class HomeController {
public static $inject = [
'$scope',
'$location',
'MovieService'
];
constructor(private $scope: IHomeControllerScope, private $location: ng.ILocationService, private MovieService) {
this.$scope.$on('$locationChangeSuccess', (event) => {
this.setActiveUrlPart();
});
MovieService.getMoviesToDownload().then(response => {
this.$scope.moviesToDownload = response;
});
}
private setActiveUrlPart() {
var parts = this.$location.path().split('/');
this.$scope.active = parts[1];
}
public get moviesToDownload() {
return this.$scope.moviesToDownload;
}
public markMovieAsDownloaded(movie: any) {
movie.Downloaded = true;
}
public deleteMovieFromDownloadList(movie: any) {
this.MovieService.deleteMovieFromDownloadList(movie).then(() => {
debugger;
this.$scope.moviesToDownload = _.without(this.$scope.moviesToDownload, movie);
});
}
}
}
app.controller("HomeController", movieApp.HomeController);
一切正常,但在this.$scope.moviesToDownload=\uu.without(this.$scope.moviesToDownload,movie)行中的方法deleteMovieFromDownloadList
,此
指的是窗口对象,而不是我期望的实际对象
生成的JavaScript如下所示:
var movieApp;
(function (movieApp) {
var HomeController = (function () {
function HomeController($scope, $location, MovieService) {
var _this = this;
this.$scope = $scope;
this.$location = $location;
this.MovieService = MovieService;
this.$scope.$on('$locationChangeSuccess', function (event) {
_this.setActiveUrlPart();
});
MovieService.getMoviesToDownload().then(function (response) {
_this.$scope.moviesToDownload = response;
});
}
HomeController.prototype.setActiveUrlPart = function () {
var parts = this.$location.path().split('/');
this.$scope.active = parts[1];
};
Object.defineProperty(HomeController.prototype, "moviesToDownload", {
get: function () {
return this.$scope.moviesToDownload;
},
enumerable: true,
configurable: true
});
HomeController.prototype.markMovieAsDownloaded = function (movie) {
movie.Downloaded = true;
};
HomeController.prototype.deleteMovieFromDownloadList = function (movie) {
var _this = this;
this.MovieService.deleteMovieFromDownloadList(movie).then(function () {
debugger;
_this.$scope.moviesToDownload = _.without(_this.$scope.moviesToDownload, movie);
});
};
HomeController.$inject = [
'$scope',
'$location',
'MovieService'
];
return HomeController;
})();
movieApp.HomeController = HomeController;
})(movieApp || (movieApp = {}));
app.controller("HomeController", movieApp.HomeController);
//# sourceMappingURL=HomeController.js.map
var myController = new HomeController();
someFramework.doSomethingWithCallback(myController.deleteMovieFromDownloadList);
如您所见,在生成的JS中,特定方法使用了_this。这看起来不错,对吧
有人能给我解释一下发生了什么以及如何解决这个问题吗
编辑:
我将其与角度测量结合使用:
编辑二:
在尝试了所有的建议,然后将我在这里发布的原始代码放回原处后,一切正常!我不知道怎么做,但我想这与Chrome/VS2013有关。无论如何,感谢那些试图帮助我的人。我猜问题在于如何调用
deleteMovieFromDownloadList
。如果您这样做:
var movieApp;
(function (movieApp) {
var HomeController = (function () {
function HomeController($scope, $location, MovieService) {
var _this = this;
this.$scope = $scope;
this.$location = $location;
this.MovieService = MovieService;
this.$scope.$on('$locationChangeSuccess', function (event) {
_this.setActiveUrlPart();
});
MovieService.getMoviesToDownload().then(function (response) {
_this.$scope.moviesToDownload = response;
});
}
HomeController.prototype.setActiveUrlPart = function () {
var parts = this.$location.path().split('/');
this.$scope.active = parts[1];
};
Object.defineProperty(HomeController.prototype, "moviesToDownload", {
get: function () {
return this.$scope.moviesToDownload;
},
enumerable: true,
configurable: true
});
HomeController.prototype.markMovieAsDownloaded = function (movie) {
movie.Downloaded = true;
};
HomeController.prototype.deleteMovieFromDownloadList = function (movie) {
var _this = this;
this.MovieService.deleteMovieFromDownloadList(movie).then(function () {
debugger;
_this.$scope.moviesToDownload = _.without(_this.$scope.moviesToDownload, movie);
});
};
HomeController.$inject = [
'$scope',
'$location',
'MovieService'
];
return HomeController;
})();
movieApp.HomeController = HomeController;
})(movieApp || (movieApp = {}));
app.controller("HomeController", movieApp.HomeController);
//# sourceMappingURL=HomeController.js.map
var myController = new HomeController();
someFramework.doSomethingWithCallback(myController.deleteMovieFromDownloadList);
…someFramework
将在不将回调绑定到预期上下文的情况下调用回调。如果是这种情况,可以通过执行以下操作进行修复:
var boundCallback = myController.deleteMovieFromDownloadList.bind(myController);
someFramework.doSomethingWithCallback(boundCallback);
更新:
在阅读Angular文档时,您在click处理程序中输入的似乎不是真正的JavaScript,而是Angular解释的。因此,可能homeCtrl.deleteMovieFromDownloadList(m)
本质上是这样做的:
var fn = homeCtrl.deleteMovieFromDownloadList;
fn(m):
…这当然不会正确设置
控制器设置好了,你就不能这样做吗
data-ng-click="deleteMovieFromDownloadList(m)"
“deleteMovie…”函数可能绑定到按钮或其他UI元素。在这种情况下,此函数在窗口上下文中执行。要解决此问题,应在控制器的构造函数中定义函数体:
constructor(private $scope: IHomeControllerScope, private $location: ng.ILocationService, private MovieService) {
// other initialization code...
this.deleteMovieFromDownloadList = (movie: any) => {
this.MovieService.deleteMovieFromDownloadList(movie).then(() => {
debugger;
this.$scope.moviesToDownload = _.without(this.$scope.moviesToDownload, movie);
});
}
}
并在控制器类中声明适当的函数:
deleteMovieFromDownloadList: (movie: any) => void;
Javascript在构造函数时有一些奇怪的行为。我举了一个例子来说明它是如何工作的:
function myClass() {
var me = this;
this.property = 'test';
this.windowObj = function() {
windowObjTest();
}
var windowObjTest = function() {
console.log(this); // this = window object
}
this.myself = function() {
myselfTest();
}
var myselfTest = function() {
console.log(me); // me = this object
}
}
var myobj = new myClass();
myobj.windowObj();
myobj.myself();
this.windowObj()
是一个公共函数,用于调用私有函数windowObjTest()代码>。在私有函数中,这个
是对窗口对象的引用,而不是对这个实例的引用(别问我,dev很高或者其他什么…)。要将当前对象的引用获取到私有函数中,必须将当前对象的引用设置到构造函数中:var me=this代码>
试试这个例子,看看控制台。应出现两个条目:
- Window test.php //console.log(this);
- myClass { property="test", windowObj=function(), myself=function()} //console.log(me);
“deleteMovie…”函数可能绑定到按钮或其他UI元素。在这种情况下,此函数在窗口上下文中执行。要解决此问题,您应该在控制器的构造函数中定义函数体:this.deleteMovieFromDownloadList=(movie:any)=>{this.MovieService.deleteMovieFromDownloadList(movie)。然后(()=>{debugger;this.$scope.moviesToDownload=41;不带(this.$scope.moviesToDownload,movie);});}我总是在构造函数中移动这样的函数。我确信这是解决TypeScript控制器中“this”问题的最简单的方法。谢谢,但不行,因为该方法不在$scope
上。这就是我使用ControllerAs
语法的原因。谢谢,我对这一点很熟悉。正如您在生成的JS代码中所看到的,它已经做到了您所暗示的:var\u this=this这正是我不理解它为什么不工作的原因,因为在该函数的回调中它使用了\u this
。我不确定在这种情况下这是否正确。您必须在类构造函数中设置_this=this才能使用它,而不是私有函数HomeController.prototype.deleteMovieFromDownloadList
。在这里,您可以用窗口对象覆盖它。我认为这是正确的,因为在调试器中,我可以看到当调用\u this=this
时,this
引用了正确的对象。您也可以使用lambda外部控制器声明函数:deleteMovieFromDownloadList=(movie:any)=>{…}