2016-06-29 4 views
3

Beim Wechsel von $ scope zu "controller as" Syntax, stoße ich auf Probleme mit der "this" Referenz. Ich muss einen Dienst anrufen, um einige Daten für das erste Laden der Seite zu erhalten. Aber das "dies" bezieht sich auf das globale Fensterobjekt und nicht auf eine Instanz des Trainingscontrollers. Etwas merkwürdig. Hier ist, was ich weiß.

Die AngularJS Aufnahme in meiner Hauptseite ...

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

Hier ist, wie der Controller in die Vorlage Seite geleitet wird.

<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> 

Hier ist die Initialisierungsfunktion von 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; 
    }); 
} 

Und schließlich gibt es den Stack-Trace von 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) 

Also, was das hinterlässt bei mir ein Datalist-Objekt, das noch nicht definiert ist nach einer Definition explizit festlegen. Irgendwelche Ideen, was getan werden kann, um dies zu beheben oder dieses Problem zu umgehen?

Antwort

3

Dies ist ein sehr typisches Problem. Die Art, wie die Callback-Funktion versprochen wird, ruft sie im globalen Kontext auf. Sie müssen Callback-Funktion binden Kontext an die Steuerung:

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

oder einfach arrow function verwenden, die lexikalischen Gültigkeitsbereich bewahrt:

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

Ein anderes Muster ist ein Verweis auf den übergeordneten Bereich zu speichern. etwas wie 'var ec = this;' an der Spitze des Controllers –

+0

Bindung an Controller-Kontext hat den Trick. Danke, dfsq. –

+0

Wahr, für controllerAls benutzen Leute manchmal etwas wie 'var $ ctrl = this;' und fügen dann alles an '$ ctrl' an. – dfsq

0

wenn Sie

var vm = this; 

setzen Sie vm statt diese verwenden können irgendwo! :)

Verwandte Themen