如何在Angular2中检测@Input()值的变化 [英] How to detect when an @Input() value changes in Angular2

查看:173
本文介绍了如何在Angular2中检测@Input()值的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父组件( CategoryComponent ),一个子组件( videoListComponent )和一个ApiService。

I have a parent component (CategoryComponent), a child component (videoListComponent) and an ApiService.

我有大部分工作正常,即每个组件都可以访问json api并通过观察器获取相关数据。

I have most of this working fine i.e. each component can access the json api and get its relevant data via observables.

目前视频列表组件只是获取所有视频,我会喜欢过滤这个只是一个特定的类别的视频,我通过 @Input()将categoryId传递给孩子,实现了这一点。

Currently video list component just gets all videos, I would like to filter this to just videos in a particular category, I achieved this by passing the categoryId to the child via @Input().

CategoryComponent.html

CategoryComponent.html

<video-list *ngIf="category" [categoryId]="category.id"></video-list>

这是有效的,当父类CategoryComponent类别更改时,categoryId值通过 @Input()但是我需要在VideoListComponent中检测到这一点,并通过APIService(使用新的categoryId)重新请求视频数组。

This works and when the parent CategoryComponent category changes then the categoryId value gets passed through via @Input() but I then need to detect this in VideoListComponent and re-request the videos array via APIService (with the new categoryId).

在角度1中,我将在变量上执行一个 $ watch 。最好的方法是处理这个问题?

In angular1 I would have done a $watch on the variable. What is the best way to handle this?

推荐答案

实际上,有两种方法可以检测和执行在角度2 +中的子组件的输入更改:


  1. 可以使用ngOnChanges()生命周期方法在答案之前:

  1. You can use the ngOnChanges() lifecycle method as mentioned in the answers before my answer:

@Input() categoryId: string;

ngOnChanges(changes: SimpleChanges) {

    this.doSomething(changes.categoryId.currentValue);
    // You can also use categoryId.previousValue and 
    // categoryId.firstChange for comparing etc.

}

有关文档,请参阅: ngOnChanges, SimpleChanges, SimpleChange

For documentation, refer to: ngOnChanges, SimpleChanges, SimpleChange

或者,您也可以使用输入设置器,如下所示:

Alternately, you can also use the input setter as follows:

private _categoryId: string;

@Input() set categoryId(value: string) {

   this._categoryId = value;
   this.doSomething(this._categoryId);

}

get categoryId(): string {

    return this._categoryId;

}


有关文档,请参阅此处

您应该使用哪种方法?

如果您的组件有多个输入,如果使用ngOnChanges(),您将在ngOnChanges()中同时获取所有输入的所有更改。使用这种方法,您还可以比较已更改的输入的当前值和以前的值,并相应地执行操作。

If your component has several inputs, then, if you use ngOnChanges(), you will get all changes for all the inputs at once within ngOnChanges(). Using this approach, you can also compare current and previous values of the input that has changed and take actions accordingly.

但是,如果您只想做某事单输入更改(您不关心其他输入),那么使用setter可能会更简单。但是,使用这种方法,您无法比较以前和当前的值,您可以使用ngOnChanges()方法更改输入值。

However, if you want to do something when only a particular single input changes (and you don't care about the other inputs), then it might be simpler to use a setter. However, with this approach, you cannot compare previous and current values of the changed input, which you can do with ngOnChanges().

EDIT 2017-07- 25:角度变化检测可能在某些情况下不会发生

通常,当父组件更改数据时,setter和ngOnChanges的更改检测将触发如果数据是JS原始数据类型(string,number,boolean),则传递给小孩。然而,在以下情况下,它不会触发,您必须采取额外的操作才能使其正常工作。

Normally, change detection for both setter and ngOnChanges will fire whenever the parent component changes the data it passes to the child, provided that the data is a JS primitive datatype(string, number, boolean). However, in the following scenarios, it will not fire and you have to take extra actions in order to make it work.


  1. 如果您正在使用嵌套的对象或数组(而不是JS原始数据类型)将数据从Parent传递给Child,则更改检测(使用setter或ngchanges)可能不会触发,如用户的答复:muetzerich所述。有关解决方案,请查看此处

如果您在角度上下文(即外部)之外突变数据,则角度将不知道更改。您可能需要在组件中使用ChangeDetectorRef或NgZone来使角度意识到外部变化,从而触发更改检测。请参阅

If you are mutating data outside of the angular context (i.e., externally), then angular will not know of the changes. You may have to use ChangeDetectorRef or NgZone in your component for making angular aware of external changes and thereby triggering change detection. Refer to this.

这篇关于如何在Angular2中检测@Input()值的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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