2015-01-09 21 views
3

鑑於這段代碼:爲什麼'this'在此TypeScript片段中引用'window'?

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 = _.without(this.$scope.moviesToDownload, movie);的方法deleteMovieFromDownloadListthis指的不是實際的對象我預計到窗口對象。

生成的JavaScript看起來像這樣:

​​

正如你所看到的,所產生的JS,具體方法使用_this。這看起來不錯,對吧?

有人可以向我解釋發生了什麼,以及如何解決這個問題?

編輯:

我已經使用這個與角度:

<body data-ng-app="movieApp" data-ng-controller="HomeController as homeCtrl"> 
    <div class="col-sm-1"> 
    <i class="fa fa-trash-o" data-ng-click="homeCtrl.deleteMovieFromDownloadList(m)" title="Verwijder uit lijst"></i> 
    </div> 
</body> 

編輯II: 嘗試所有的建議,然後設置回原來的代碼我已經張貼在這裏,一切之後只是工作正常!我不知道如何,但我想這與Chrome/VS 2013有關。無論如何,感謝那些試圖幫助我的人。

+0

可能「deleteMovie ...」函數綁定到按鈕或其他UI元素。在這種情況下,該功能在窗口上下文中執行。要解決該問題,您應該在控制器的構造函數中定義函數體:this.deleteMovieFromDownloadList =(movie:any)=> this.MovieService.deleteMovieFromDownloadList(movie).then(()=> { debugger; this。$ scope.movi​​esToDownload = _.without(this。$ scope.movi​​esToDownload,movie); }); } – TSV

+0

我總是在構造函數中移動這樣的函數。我確定這是在TypeScript控制器中用「this」解決問題的最簡單方法。 – TSV

回答

2

可能「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; 
+0

你可以用lambda外部控制器聲明函數:'deleteMovieFromDownloadList =(movie:any)=> {...}' –

2

我猜測問題在於如何調用deleteMovieFromDownloadList。如果你做這樣的事情:

var myController = new HomeController(); 
someFramework.doSomethingWithCallback(myController.deleteMovieFromDownloadList); 

... someFramework最終會調用而不會被綁定到預期的背景下回調。如果是這樣的話,你可以這樣修復:

var boundCallback = myController.deleteMovieFromDownloadList.bind(myController); 
someFramework.doSomethingWithCallback(boundCallback); 

更新:

在通過角文檔閱讀,看來你把單擊處理程序究竟是不是真的JavaScript,但由Angular解釋。因此,也許homeCtrl.deleteMovieFromDownloadList(m)正在做這樣的事情主要有:

var fn = homeCtrl.deleteMovieFromDownloadList; 
fn(m): 

...這當然不會設置this正確。

隨着控制器的設置,你不能這樣做嗎?

data-ng-click="deleteMovieFromDownloadList(m)" 
+0

謝謝,但不,我不能這樣做,因爲該方法不在'$ scope'上。這就是我使用'ControllerAs'語法的原因。 – Martijn

1

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();。在一個私有函數中,this是對窗口對象的引用,而不是這個實例(不要問我,開發者是高的還是...)。要將當前對象引用到私有函數中,必須將當前對象的引用設置爲構造函數:var me = this;

試一下例子,看看控制檯。應出現兩個條目:

- Window test.php //console.log(this); 
- myClass { property="test", windowObj=function(), myself=function()} //console.log(me); 
+0

謝謝,我對此很熟悉。正如你在生成的JS代碼中看到的那樣,它已經做了你所暗示的:'var _this = this;'這正是我不明白爲什麼它不起作用的原因,因爲在該函數的回調中它使用'_this'。 – Martijn

+0

我不確定_this =在這種情況下這是否正確。你必須在類構造函數中設置_this = this來使用它,而不是私有函數'HomeController.prototype.deleteMovieFromDownloadList'。在這個地方,你用窗口對象覆蓋_this。 – Tyr

+0

我認爲這是正確的,因爲在調試器中,我可以看到當_this = this被調用時,this指的是正確的對象。 – Martijn

相關問題