我有一个父控制器UserEditCtrl
和一个子控制器EditUserCtrl
。在我的父控制器内部,我通过服务提取用户对象:
userMgmtSvc.user(scope.editUserId).then(function(data) {
this.user = data;
});
然后我想将我的用户对象的属性设置为另一个变量。
this.selectedRoles = this.user.roles;
但这会引发错误:
Cannot read property 'user' of undefined.
我对如何引用使用this
设置的对象感到困惑。例如,我如何只是console.log对象?因为console.log('user', this.user);
返回undefined:
user undefined
这是父控制器:
(
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 :(得分:3)
这是一个非常基本的错误,当您在回调中引用this
当前上下文时,您不了解执行上下文并最终在其他位置设置值。
为了避免陷入此问题,当您的控制器启动时,只需将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来创建绑定函数(函数引用预绑定指定的上下文),但最简单的方法是使用缓存的上下文。
当您使用打字稿时,您可以使用=>
(胖箭头)语法,因为ES5模式中的打字稿实际上会转换它。
userMgmtSvc.user(scope.editUserId).then((data) => {
this.user = data;
});
来: -
var _that = this;
userMgmtSvc.user(scope.editUserId).then((data) => {
_that.user = data;
});
在Arrow functions时,the engines starts supporting the arrow function syntax将成为语言本身的一部分(使用ES6规范)。所以使用ES6你可以安全地写: -
userMgmtSvc.user(scope.editUserId).then((data) => {
this.user = data;
});