【问题标题】:cannot get 'this' of component inside subscribe function无法在订阅函数中获取组件的“this”
【发布时间】:2016-08-24 08:35:11
【问题描述】:

我的问题与这些非常相似,但我没有解决我的问题;

cannot access to this of component in subscribe function

'this' scope in typescript callback function

Cannot Access Component Variables in Subscribe when using chrome inspector

unable to get component variables inside a RxJS subscribe() function

这是我的打字稿组件类:

export class Test{
     x: string;
}

export class TestComponent implements OnInit{
     test: Test;

     constructor(private testService: TestService){}

     ngOnInit(){
          this.testService.getTest()
               .subscribe((res) => { this.test = res.test;}, ...);
          console.log(this.text.x) //it becomes undefined
     }
}

我正在使用 gulp-typescript,输出是这样的;

//when targeting es6

let testComponent = class TestComponent ... {
     constructor(testService){
          this.testService = testService;
     }

     ngOnInit(){
          this.testService.getTest()
               .subscribe((res) => {this.test = res.test;}, ...);
          console.log(this.text.x)
     }
}

//when targeting es5

var TestComponent = (function(){
     function TestComponent(testService){
         this.testService = testService;
     }

     TestComponent.prototype.ngOnInit = function(){
          var _this = this;
          this.testService.getTest()
               .subscribe(function (res) { _this.test = res.test }, ...);
          console.log(this.text.x)
     }
}())

当我想尝试访问“this.test.x”时,我从浏览器收到以下错误,同时输出;

EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property 'x' of undefined

当我登录this.test 时,它是undefined。我的 TestService 被正确注入,请求来到我的 api,res.test 包含我需要的内容,但我不能与this.test 一起使用,因为它始终未定义。我不知道我在哪里做错了。还有其他人可以帮助我吗?最后我想问一下,考虑浏览器兼容性等,es5还是es6,我应该针对哪一个?

【问题讨论】:

  • 什么是'whateverItIs'。我没有在您发布的代码中看到这一点?展开构造函数并添加console.log(testService) 以确保服务正在传递/注入到构造函数中。
  • 它只是我的测试类的任何属性,我写了属性名称的“whateverItIs”。 TestService 注入正确,我的 api 得到请求。
  • 能否请您包含一些来自您的测试类的代码。谢谢。我只是想看看真正的属性名称是什么,这样我就可以看到哪个对象是undefined
  • 好的。这对我来说很有意义。我希望您在 ngOnInit 上调用 console.log(this.test.x) 会出现错误。根据您提供的代码, this.test 至少要到 VM 的下一个“回合”才会填充。尽管您可以在收到预期数据的订阅回调中调用它。这将是预期的行为。在您的订阅回调之前调用 console.log()。您需要转到回调。
  • 最后一件事,对于浏览器目标 ES5。大多数移动浏览器尚不支持 ES6(截至目前),只有最新的桌面浏览器才会支持 ES6。最后,这些浏览器中的 ES6 实现并没有像 ES5 实现那样优化。

标签: javascript asynchronous angular typescript scope


【解决方案1】:

console.log 语句移到箭头函数内。

ngOnInit(){
          this.testService.getTest()
               .subscribe((res) => {
                 this.test = res.test;
                 console.log(this.text.x)
          }, ...);

     }

如果您想对this.test 做其他事情,那么您也必须将它们移到内部(或者,添加另一个函数并从回调内部调用它)。基本上,如果您有一个返回 Observable 的服务,这意味着回调将不会在您调用该函数的同一“框架”中运行。在您的原始代码中,这是操作顺序:

  1. getTest 被调用,AJAX 操作开始
  2. console.log 调用,打印未定义。
  3. 在请求与服务器通信时,用户获得了一秒钟的 UI 时间,而不会发生太多事情
  4. 请求完成,subscribe(() => 回调被调用。 this.test 已设置。

【讨论】:

  • 这里是异步编程更深入解释的链接。这不是特定于 Angular2 或 TypeScript code.tutsplus.com/tutorials/…
  • 如果我想在[formGroup] 中使用this.test.x 怎么办?当我在订阅中调用它时,我得到了错误,或者我应该使用模板驱动的表单而不是 ReactiveForms? @Katana314 @Martin
  • 您可能只想用*ngIf="test" 包装您的表单。这样,在您的数据返回之前,不会调用表单中的表单和对test.x 的引用。另一种选择是使用async 管道。或者两者的结合。
【解决方案2】:

“_this.componentProperty”在“subscribe()”rxjs 调用中对我有用,而不是“this.componentProperty”。

【讨论】:

  • 有效,但在编辑器中被标记为错误,因为 _this 未定义。
【解决方案3】:

您可以将您的函数 TestComponent.prototype.ngOnInit 替换为箭头函数,这样“this”就可以从您的订阅调用中访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2021-02-25
    • 2022-09-27
    • 2018-05-01
    相关资源
    最近更新 更多