2016-06-29 4 views
3

$ scopeから "controller as"構文に切り替えるときに、 "this"の参照に問題があります。最初のページを読み込むためのデータを取得するためにサービスを呼び出す必要があります。しかし、私が取得する「これ」は、エクササイズコントローラのインスタンスではなく、グローバルウィンドウオブジェクトを指します。少しおかしな。ここに私が知っているものがあります。

私のメインページでAngularJS含める...

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script> 

はここで、コントローラは、テンプレートページに含まれます方法です。ここで

<div class="col-xs-9" 
     ng-include="'exercise/exercise_body.html'" 
     ng-show="mainController.showStatus.exercises" 
     ng-controller="ExerciseController as ec" 
     ng-init="ec.initialize()"></div> 

はExerciseControllerから初期化関数です。

this.initialize = function(){ 
    // Item lists to display on different parts of the page 
    this.dataList = {}; 
    this.dataList.exercises = []; 
    this.dataList.resources = []; 

    var promise = exerciseService.getExercises(); 
    promise.then(function(res){ 
     console.log(this); // this is a window object? why???? 
     this.dataList.exercises = res.data.exercises; 
    }); 
} 

そして最後に、Chromeからスタックトレースがある....

TypeError: Cannot set property 'exercises' of undefined 
at app.js:82 
at angular.js:13189 
at l.$eval (angular.js:14401) 
at l.$digest (angular.js:14217) 
at l.$apply (angular.js:14506) 
at l (angular.js:9659) 
at S (angular.js:9849) 
at XMLHttpRequest.D.onload (angular.js:9790) 

それでは、それは私を残しすることも、明示的な定義を設定した後に未定義だデータリストオブジェクトです。これを修正するために何ができるか、またこの問題を回避するためのアイデアはありますか?

答えて

3

これは非常に典型的な問題です。約束のためにコールバック関数が提供される方法は、それをグローバルコンテキストで呼び出すことができます。あなたは、コンテキストをコントローラにコールバック関数をバインドする必要があります。

var promise = exerciseService.getExercises(); 
promise.then(function(res) { 
    this.dataList.exercises = res.data.exercises; 
}.bind(this)); 

または単にレキシカルスコープを維持するarrow functionを使用します。

var promise = exerciseService.getExercises(); 
promise.then(res => this.dataList.exercises = res.data.exercises); 
+2

もう1つのパターンは、親スコープへの参照を格納することです。コントローラーの上部にある 'var ec = this;'のようなもの –

+0

コントローラーのコンテキストへのバインドがトリックでした。ありがとう、dfsq。 –

+0

trueの場合、controllerAsの場合、 'var $ ctrl = this;'のようなものを使用し、すべてを '$ ctrl'に添付することがあります。 – dfsq

0

あなたは

var vm = this; 

を置く場合は、このの代わりにVMを使用することができますどこにでも! :)

関連する問題