[英]Confusion about 'this' keyword in angular 'controller as' syntax
I have a parent controller, UserEditCtrl
and a child controller, EditUserCtrl
. 我有一个父控制器UserEditCtrl
和一个子控制器EditUserCtrl
。 Inside of my parent controller I am pulling in a user object via a service: 在父控制器内部,我通过服务引入用户对象:
userMgmtSvc.user(scope.editUserId).then(function(data) {
this.user = data;
});
Then I want to set a property of my user object to another variable. 然后,我想将用户对象的属性设置为另一个变量。
this.selectedRoles = this.user.roles;
But this throws an error: 但这会引发错误:
Cannot read property 'user' of undefined.
I'm confused as to how I reference objects that are set with this
. 我对如何引用使用this
设置的对象感到困惑。 For example, how do I just console.log the object? 例如,如何仅console.log对象? Because console.log('user', this.user);
因为console.log('user', this.user);
returns undefined: 返回未定义:
user undefined
Here's the parent controller: 这是父控制器:
(
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)
);
This is a very basic mistake that happens when you refer to the current context with this
inside a callback about which you don't know about the execution context and you end up setting values elsewhere. 这是一个非常基本的错误,当你指的是当前上下文与发生this
回调,你不知道的执行上下文哪些内,你最终会在其他地方设置值。
In order to avoid getting into this issue, when your controller starts just set this
(context of controller instance) to a variable and set everything on that. 为了避免出现此问题,在控制器启动时,只需将this
(控制器实例的上下文)设置为变量并对其进行所有设置。 Don't assume what this
is going to be. 不要以为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
}
There are numerous other ways to do this using angular.bind, or es5 function.bind to create a bound functions (function reference pre bound with a specified context), but easiest way would be to use a cached context. 还有许多其他方法可以使用angular.bind或es5 function.bind创建绑定函数(以指定上下文为前缀的函数引用),但是最简单的方法是使用缓存的上下文。
When you are using typescript you could use a =>
(fat arrow) syntax since typescript in ES5 mode will actually convert this. 当您使用打字稿时,可以使用=>
(胖箭头)语法,因为ES5模式下的打字稿实际上会对此进行转换。
userMgmtSvc.user(scope.editUserId).then((data) => {
this.user = data;
});
to:- 至:-
var _that = this;
userMgmtSvc.user(scope.editUserId).then((data) => {
_that.user = data;
});
Arrow functions are going to be part of the language itself (with ES6 specifications) when the engines starts supporting the arrow function syntax . 当引擎开始支持箭头函数语法时, 箭头函数将成为语言本身(具有ES6规范)的一部分。 So with ES6 you could safely write:- 因此,使用ES6,您可以放心地写:
userMgmtSvc.user(scope.editUserId).then((data) => {
this.user = data;
});
Here is an excellent answer that specifically targets this
这是专门针对this
问题的出色答案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.