简体   繁体   English

Angular:为什么我不能使用组件的方法作为可观察的回调来更新组件的属性?

[英]Angular: why can't I use a method of my component as an obserable callback to update properties in the component?

I am following this link on how to use service to make http request in Angular and update my list of items in a component. 我正在关注此链接 ,了解如何使用服务在Angular中发出http请求并更新组件中的项目列表。 I can successfully do it with fat arrow function as obserable callback. 我可以使用胖箭头功能作为可观察的回调成功完成此操作。 But when I try to use a method in my component, it failed to update the list of items. 但是,当我尝试在组件中使用一种方法时,它无法更新项目列表。

for example: 例如:

import { Component, OnInit } from '@angular/core';
import { BlogService } from '../blog.service';
import { Blog } from '../blog';
import { Observable, of } from 'rxjs';

@Component({
  selector: 'app-articles',
  templateUrl: './articles.component.html',
  styleUrls: ['./articles.component.css']
})
export class ArticlesComponent implements OnInit {
  blogs: Blog[];
  constructor(private blogService: BlogService) { }

  ngOnInit() {
    // const handler = (incomingBlogs: Blog[]) => {
    //   this.blogs = incomingBlogs;
    //   console.log("we get: ", this.blogs);
    // }

    const observable: Observable<Blog[]> = this.blogService.getBlogs();
    // observable.subscribe(handler); <===== this will work
    // observable.subscribe(incomingBlogs => {this.blogs = incomingBlogs;  console.log("fat get: ", this.blogs);}); <====== this also work
    observable.subscribe(this.handler); // <===== this failed. 
    console.log("this in init", this);
  }

  handler(incomingBlogs: Blog[]) {
    this.blogs = incomingBlogs;
    console.log("we get: ", this.blogs);
    console.log("this in handler", this); //seems the this keyword refers to something different than the object itself.
  }

}

I tried three approaches to update the list of blogs 我尝试了三种方法来更新博客列表

  1. fat arrow inside the subscribe as callback. 订阅中的粗箭头作为回调。 this works! 这可行!

  2. define a constant and assign a fat arrow function to it. 定义一个常量并为其分配一个粗箭头功能。 pass it to subscribe function. 传递给订阅功能。 It works too, just like option 1. And I understand as they behave the same. 它也可以工作,就像选项1一样。据我所知,它们的行为相同。

  3. define a method in the same class (the component). 在同一类(组件)中定义一个方法。 Use it as callback for the subscribe function. 用作预订功能的回调。 The method is called. 该方法被调用。 But this keyword does not seem to refer to a component. 但是this关键字似乎并不指向组件。 Why is it different? 为什么不同? I understand that in the world of javascript, function keyword gives you a whole different this . 我了解在javascript的世界中,function关键字this提供了完全不同的this But why does it happen in a method of a class in TypeScript? 但是,为什么它会在TypeScript中的类方法中发生? Why does the this mean different objects here? 为什么this意味着这里有不同的对象? Why does fat arrow work ? 为什么胖箭头起作用?

I have searched for the answers before but get no luck. 我之前一直在寻找答案,但是没有运气。 (I must haven't used the correct keywords). (我一定没有使用正确的关键字)。 Thanks for your help! 谢谢你的帮助!

Fat arrow functions always are bound to the object they are defined in, a function will be bound to the object they are called from. 粗箭头函数始终绑定到定义它们的对象,函数将绑定到调用它们的对象。 Change your handler to an arrow function. 将处理程序更改为箭头功能。

handler = (incomingBlogs: Blog[]) => {
    this.blogs = incomingBlogs;
    console.log("we get: ", this.blogs);
    console.log("this in handler", this); //seems the this keyword refers to something different than the object itself.
  }

If you put a break point in your current function you will see that this points to the observable that it is called from. 如果在当前函数中放置一个断点,您将看到它指向从中调用的可观察对象。

If you want to use a normal function you could pass this in as a paramater 如果您想使用普通功能,可以将其作为参数传递

  handler(incomingBlogs: Blog[], controller: ArticlesComponent) {
    controller.blogs = incomingBlogs;
    console.log("we get: ", controller.blogs);
    console.log("this in handler", controller); //seems the this keyword refers to something different than the object itself.
  }

But my advice would be to not subscribe to observables in the controller and use the async pipe in your view. 但是我的建议是不要在控制器中订阅可观察对象,并在视图中使用异步管道。

blogs$ = this.blogService.getBlogs();

In your TypeScript and in your view 在您的TypeScript和视图中

<ng-container *ngIf="blogs$ | async as blogs">
    Use blogs here as you would have before
    {{blogs | json}}
</ng-container>

Then you have the view managing your subscription for you and you don't have to worry about orphan subscriptions. 然后,您便可以使用视图为您管理订阅,而不必担心孤立订阅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM