首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当@Input()值在Angular中发生变化时,如何检测?

当@Input()值在Angular中发生变化时,如何检测?
EN

Stack Overflow用户
提问于 2016-07-25 23:28:01
回答 16查看 446.9K关注 0票数 679

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

我已经很好地完成了大部分工作,即每个组件都可以访问json api,并通过可观察对象获取相关数据。

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

CategoryComponent.html

代码语言:javascript
复制
<video-list *ngIf="category" [categoryId]="category.id"></video-list>

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

在AngularJS中,我会对变量执行一次$watch。处理这个问题的最好方法是什么?

EN

回答 16

Stack Overflow用户

回答已采纳

发布于 2017-06-22 04:53:36

实际上,当angular2+中的子组件中的输入发生变化时,可以通过两种方式进行检测和操作:

  1. 您可以使用ngOnChanges()生命周期方法,如旧答案:

中所述

代码语言:javascript
复制
    @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, SimpleChanges, SimpleChange

演示示例:查看this plunker

  1. Alternately,您还可以使用输入属性设置器,如下所示:

代码语言:javascript
复制
    private _categoryId: string;
    
    @Input() set categoryId(value: string) {
    
       this._categoryId = value;
       this.doSomething(this._categoryId);
    
    }
    
    get categoryId(): string {
    
        return this._categoryId;
    
    }

文档链接:查看here

演示示例:查看this plunker

您应该使用哪种方法?

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

但是,如果您想在只有一个特定的输入更改时执行某些操作(而不关心其他输入),那么使用输入属性设置器可能会更简单。但是,这种方法没有提供一种内置的方法来比较更改后的输入的以前和当前值(使用ngOnChanges生命周期方法可以很容易地做到这一点)。

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

通常,只要父组件更改了它传递给子组件的数据,只要数据是JS原始数据类型(字符串、数字、布尔值),就会触发对setter和ngOnChanges的更改检测。但是,在以下情况下,它将不会触发,您必须采取额外的操作才能使其工作。

  1. 如果您使用嵌套对象或数组(而不是JS基元数据类型)将数据从父对象传递给子对象,则可能不会触发更改检测(使用setter或ngchange),这在user: muetzerich的回答中也有提到。有关解决方案,请查看here.

  1. 如果您在angular上下文之外(即,外部)更改数据,则angular将不会知道这些更改。您可能必须在组件中使用ChangeDetectorRef或NgZone,以使angular感知外部更改,从而触发更改检测。请参阅this.
票数 1.1K
EN

Stack Overflow用户

发布于 2016-07-25 23:31:56

在组件中使用ngOnChanges()生命周期方法。

在检查完数据绑定属性之后,如果视图和内容子级中至少有一个发生了更改,则会在检查它们之前立即调用

ngOnChanges。

这是Docs

票数 117
EN

Stack Overflow用户

发布于 2016-10-07 03:47:44

在函数签名中使用SimpleChanges类型时,我在控制台、编译器和集成开发环境中遇到错误。为防止出现错误,请在签名中使用any关键字。

代码语言:javascript
复制
ngOnChanges(changes: any) {
    console.log(changes.myInput.currentValue);
}

编辑:

正如Jon在下面指出的,在使用括号表示法而不是点表示法时,可以使用SimpleChanges签名。

代码语言:javascript
复制
ngOnChanges(changes: SimpleChanges) {
    console.log(changes['myInput'].currentValue);
}
票数 47
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38571812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档