2014-09-08 1 views
0

부모 컨트롤러가 UserEditCtrl이고 자식 컨트롤러가 EditUserCtrl입니다. 내 부모 컨트롤러의 내부 나는 서비스를 통해 사용자 개체 당기는 오전 :각도 '컨트롤러로'구문에서 'this'키워드에 대한 혼동

userMgmtSvc.user(scope.editUserId).then(function(data) { 
    this.user = data; 
}); 

가 그럼 난 다른 변수에 내 사용자 개체의 속성을 설정합니다.

Cannot read property 'user' of undefined. 

내가 this로 설정 객체를 참조하는 방법에 대한 혼란 스러워요 :

this.selectedRoles = this.user.roles; 

는하지만이 오류가 발생합니다. 예를 들어, 나는 단지 console.log 객체를 어떻게 만듭니 까? console.log('user', this.user); 반환 정의되지 않은 때문에 :

(
    function (app) { 
    /* @fmt: off */ 
    'use strict'; 

    // @fmt:on 
    app.controller('UserEditCtrl', ['$scope', '$http', 'userMgmtSvc', 'createUserSvc', 'authSvc', '$state', '$timeout', '$location', '_', 
     function (scope, http, userMgmtSvc, createUserSvc, authSvc, state, timeout, location, _) { 

     userMgmtSvc.user(scope.editUserId.id || sessionStorage.getItem('editUser')).then(function(data) { 
     this.user = data; 
     console.log('user', this.user); 

     // GET states 
     createUserSvc.states().then(function(data) { 
      this.states = data; 
      console.log(this.states); 
     }); 

     // GET countries 
     createUserSvc.countries().then(function(data) { 
     this.countries = data; 
     }); 

     // GET roles 
     createUserSvc.roles().then(function(data) { 
     this.roles = data; 
     }); 

     // GET insurance groups 
     createUserSvc.insuranceGroups().then(function(data) { 
     this.insuranceGroups = data; 
     }); 

     this.selectedRoles = this.user.roles; 
    }); 

}]); 

}(window.app) 
); 
+0

합니다. [올바른 'this'/콜백 내 컨텍스트에 액세스하는 방법?] (https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback)을 참조하십시오. . 또한,'this.user.roles'를 읽으려고 할 때'then' 콜백은 아직 실행되지 않았을 가능성이 높기 때문에 'this'가 설정되어 있어도 값을 설정할 수 없습니다. 올바른 개체를 참조했습니다. 더 나은 결과를 얻으려면 여기에 설명 된 ** 완전한 *** 예제를 제공해야합니다. https://stackoverflow.com/help/mcve –

+0

Felix의 말. 'then()'의 함수를'this '에 항상'.bind()'하여 올바른 키워드가되도록 할 수 있습니다. – Jhecht

답변

3

이 당신이하지 않는에 대한 콜백 내부 this와 현재 컨텍스트를 참조 할 때 발생하는 아주 기본적인 실수는 다음과 같습니다

user undefined 

상위 컨트롤러의 실행 컨텍스트에 대해 알면 다른 값을 설정하게됩니다.

이 문제가 발생하지 않도록하려면 컨트롤러가 시작될 때 this (컨트롤러 인스턴스의 컨텍스트)을 변수로 설정하고 그 모든 것을 설정하십시오. this이 될 것이라고 가정하지 마십시오.

.controller('crtl',[deps..., function(...) { 
     //Set this 
     var vm = this; //Always use this cached variable have seen a commonly used name of vm 

     //............... 
     //............... 
     userMgmtSvc.user(scope.editUserId).then(function(data) { 
     vm.user = data; 
     }); 

     //............... 
     vm.selectedRoles = vm.user.roles 

    } 

가 바운드 기능을 (지정된 문맥으로 바인드 함수 참조 사전)을 만들 수있는 수많은 다른이 사용 angular.bind을 수행하는 방법, 또는 ES5의 function.bind가 있지만 가장 쉬운 방법은 캐시를 사용하는 것 문맥.

typescript를 사용하는 경우 => (축 화살표) 구문을 사용할 수 있습니다. ESS 모드의 타이 스크립트는 실제로이를 변환하기 때문입니다.

 userMgmtSvc.user(scope.editUserId).then((data) => { 
     this.user = data; 
     }); 

에 -

var _that = this; 
    userMgmtSvc.user(scope.editUserId).then((data) => { 
     _that.user = data; 
    }); 

Arrow functions

이 (ES6 사양) 언어 자체의 일부 the engines starts supporting the arrow function syntax이 될 것입니다. ES6와 그래서 안전하게 쓸 수있다 : - 아마 컨트롤러를 참조하지 않습니다 this`은`then` 콜백,`내부

 userMgmtSvc.user(scope.editUserId).then((data) => { 
     this.user = data; 
     }); 

Here is an excellent answer that specifically targets this

+0

'_that'의 일을 설명해 주시겠습니까? '_that.selectedRoles'를'_that.user.roles'로 어떻게 설정할 수 있습니까?'_that'가 아직 정의되지 않았습니까? – reknirt

+0

_that는 컨트롤러 인스턴스의 참조 (참조 사본)를 보유하는 변수입니다. 이 변수를 사용하는 것이 실행되기 전에 컨트롤러에 정의되어 있는지 확인해야합니다. : D I h – PSL

+0

이제 viewmodel의 abbr 인 VM으로 변수 이름을 변경했습니다. – PSL