如何检测Angular中@Input()值何时更改? [英] How to detect when an @Input() value changes in Angular?

查看:103
本文介绍了如何检测Angular中@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).

在AngularJS中,我将对变量执行$watch.处理此问题的最佳方法是什么?

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

推荐答案

实际上,当输入在angular2 +的子组件中发生更改时,有两种检测和处理方法:

  1. 您可以使用 ngOnChanges()生命周期方法,如较早的答案中所述:
  1. You can use the ngOnChanges() lifecycle method as also mentioned in older answers:

    @Input() categoryId: string;
        
    ngOnChanges(changes: SimpleChanges) {
        
        this.doSomething(changes.categoryId.currentValue);
        // You can also use categoryId.previousValue and 
        // categoryId.firstChange for comparing old and new values
        
    }
    

文档链接: ngOnChanges SimpleChange
演示示例:查看此导航键

Documentation Links: ngOnChanges, SimpleChanges, SimpleChange
Demo Example: Look at this plunker

  1. 或者,您也可以如下使用 input属性设置器:

    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.

但是,如果您想在仅特定的单个输入发生更改时执行某项操作(并且您不关心其他输入),那么使用输入属性设置器可能会更简单.但是,这种方法没有提供一种内置的方式来比较更改后的输入的先前值和当前值(您可以使用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 an input property setter. However, this approach does not provide a built in way to compare previous and current values of the changed input (which you can do easily with the ngOnChanges lifecycle method).

编辑2017-07-25:在某些情况下,角度变化检测可能仍无法触发

通常,每当父组件更改传递给子代的数据时,都会触发setter和ngOnChanges的更改检测,前提是该数据是JS基本数据类型(字符串,数字,布尔值) .但是,在以下情况下,它不会启动,您必须采取额外的措施才能使其正常工作.

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基本数据类型)将数据从父级传递给子级,则更改检测(使用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.

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

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