混淆在角'这个'关键字'控制器'语法 [英] Confusion about 'this' keyword in angular 'controller as' syntax

查看:125
本文介绍了混淆在角'这个'关键字'控制器'语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个家长控制, UserEditCtrl 和子控制器, EditUserCtrl 。里面我的父母控制器我在用户对象通过服务拉动:

  userMgmtSvc.user(scope.editUserId)。然后(功能(数据){
  this.user =数据;
});

然后我想我的用户对象的属性设置为另一个变量。

  this.selectedRoles = this.user.roles;

但是,这将引发一个错误:

 无法读取未定义的属性用户。

我很困惑,我该怎么引用设置与这个的对象。例如,我怎么只CONSOLE.LOG对象?因为的console.log(用户,this.user); 返回undefined:

 用户不确定

下面是父控制器:

 
  功能(应用){
    / * @fmt:关* /
    使用严格的;    // @fmt:上
    app.controller('UserEditCtrl',['$范围,$ HTTP,userMgmtSvc','createUserSvc','authSvc','$州','$超时','$位置','_',
      功能(范围,HTTP,userMgmtSvc,createUserSvc,authSvc,州,超时,位置,_){      userMgmtSvc.user(scope.editUserId.id || sessionStorage.getItem('editUser'))。然后(功能(数据){
        this.user =数据;
        的console.log(用户,this.user);      //获取状态
      createUserSvc.states()。然后(功能(数据){
          this.states =数据;
          的console.log(this.states);
      });      //获取国家
        createUserSvc.countries()。然后(功能(数据){
        this.countries =数据;
      });      //获取角色
      createUserSvc.roles()。然后(功能(数据){
        this.roles =数据;
      });      //获取保险集团
      createUserSvc.insuranceGroups()。然后(功能(数据){
        this.insuranceGroups =数据;
      });      this.selectedRoles = this.user.roles;
    }); }]);}(window.app)
);


解决方案

这是一个非常基本的错误,当你指的是当前环境与这个的回调里面出现这种情况关于你不知道的执行上下文,你最终会在其他地方设置值。

为了避免陷入这个问题,当你的控制器启动只需设置这个(控制器实例的上下文中)给一个变量,并在该设置应有尽有。不要以为是什么这个将是

  .controller('CRTL',[DEPS ...,功能(...){
       //设置此
       VAR VM =这一点; //始终使用该缓存变量已经看到虚拟机的常用名称       // ...............
       // ...............
       userMgmtSvc.user(scope.editUserId)。然后(功能(数据){
         vm.user =数据;
       });       // ...............
       vm.selectedRoles = vm.user.roles   }

有许多其他方法可以做到这一点使用angular.bind,或ES5 function.bind创建一个约束功能(与指定的上下文约束函数参考pre),但最简单的方法是使用一个缓存的情况下

当您使用打字稿你可以使用 => (脂肪箭头)语法因为在ES5模式打字稿实际上将转化这一点。

  userMgmtSvc.user(scope.editUserId)。然后((数据)=> {
         this.user =数据;
      });

于: -

  VAR _that =这一点;
    userMgmtSvc.user(scope.editUserId)。然后((数据)=> {
         _that.user =数据;
     });

箭头功能的将要语言本身(与ES6规格)的一部分,当发动机启动配套的箭头函数语法。因此,与ES6,你可以放心地写: -

  userMgmtSvc.user(scope.editUserId)。然后((数据)=> {
         this.user =数据;
      });

<一个href=\"http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback\">Here是专门针对一个很好的答案这个

I have a parent controller, UserEditCtrl and a child controller, 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. For example, how do I just console.log the object? Because 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.

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. Don't assume what this is going to be.

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

When you are using typescript you could use a => (fat arrow) syntax since typescript in ES5 mode will actually convert this.

      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. So with ES6 you could safely write:-

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

Here is an excellent answer that specifically targets this

这篇关于混淆在角'这个'关键字'控制器'语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆