Angular 2 - 检测绑定属性何时收到值

Posted

技术标签:

【中文标题】Angular 2 - 检测绑定属性何时收到值【英文标题】:Angular 2 - detect when a bonded property receives a value 【发布时间】:2019-06-01 05:21:41 【问题描述】:

我想知道保税财产何时收到一个值,即使它是相同的值。

例如

那是一个特征组件

import 
    Component,
    OnInit,
    Input,
    OnChanges,
    SimpleChanges
 from '@angular/core';
@Component(
    selector: 'feature-component',
    templateUrl: './template.html',
    styleUrls: ['./style.sass'] 
) 
export class FeatureComponent implements OnInit, Onchanges 

    @Input() bondedProperty: any;

    ngOnInit() 

    

    ngOnChanges(simpleChanges: SimpleChanges) 
        // not called inside the setInterval function
        console.log('the bonded property received any value.');
    


应用的组件

import 
    Component,
    AfterViewInit
 from '@angular/core';
@Component(
    selector: 'app-component',
    templateUrl: './template.html',
    styleUrls: ['./style.sass'] 
) 
export class AppComponent implements AfterViewInit 

    bondedProperty: any;

    constructor() 
        this.bondedProperty = 10;
    

    ngAfterViewInit() 
        const
            interval = setInterval(
                () => 
                    this.bondedProperty = 10;
                    console.log('function called after interval');
                    clearInterval(interval);
                , 5000
            );
    


最后是应用的模板

<feature-component
    [bondedProperty]="bondedProperty"
>
</feature-component>

问题是,如果在bondedProperty 中分配了相同的值,则ngOnChanges 没有被调用,而ngDoCheck 方法并不能解决我的问题,因为我不知道“更改”是否在@ 987654327@.

【问题讨论】:

你可以在bondedpropery上使用setter和getter 使用@ViewChild,你可以调用子组件方法,这样可以帮助你 我可能有一些类似于 componentShouldUpdate 的东西,比如 Angular 和 react.. 我们得到了组件的当前状态和新状态 @benshabatnoam 在您的示例中,您在ngAfterViewInit 中将bondedProperty 设置为与构造函数中不同的值。它适用于不同的值,但如果该值与先前设置的值相同,则无效。 @Hypenate 设置器仅在属性值不同时才起作用。 【参考方案1】:

据我所知,ngOnChanges@Input setters 无法实现这一点,因为 Angular 设计为仅在值实际发生变化时调用 ngOnChangessetter

如果您想检测新值,即使它们与以前的值相同,您真正想要的可能是检测某种事件。你可以使用 RxJS BehaviorSubject 来达到这种目的。

特征组件

import  Component, OnInit, Input, OnChanges, SimpleChanges  from '@angular/core';
import  BehaviorSubject   from 'rxjs';
@Component(
    selector: 'feature-component',
    template: 'property:  bondedProperty$ | async ',
    styleUrls: ['./style.sass'] 
) 
export class FeatureComponent implements OnInit, Onchanges 

    @Input() bondedProperty$: BehaviorSubject<any>;

    ngOnInit() 
      this.bondedProperty$.subscribe(value => 
        console.log('the bonded property received any value.')
      );
    


应用组件

import  Component, AfterViewInit  from '@angular/core';
import  BehaviorSubject   from 'rxjs';
@Component(
    selector: 'app-component',
    template: '<feature-component [bondedProperty$]="bondedProperty$"></feature-component>',
    styleUrls: ['./style.sass'] 
) 
export class AppComponent implements AfterViewInit 

    bondedProperty$ = new BehaviorSubject<any>(0);

    constructor() 
        this.bondedProperty$.next(10);
    

    ngAfterViewInit() 
        const
            interval = setInterval(
                () => 
                    this.bondedProperty$.next(10);
                    console.log('function called after interval');
                    clearInterval(interval);
                , 5000
            );
    


https://stackblitz.com/edit/angular-so-54059234-eshtnr

【讨论】:

谢谢。我知道这个解决方案,但我不想使用它,因为我的问题是要在外部库中使用,而这个解决方案将需要用户更加复杂。但如果没有其他解决方案,就只能这样了。 @rplarindo 好吧,我想您必须问自己,为什么您的功能组件应该关心将输入属性设置为它已经拥有的当前值。你的组件不需要再次渲染,所以 Angular 不关心它。如果你能说出你的实际用例,人们可能会更好地帮助你。【参考方案2】:

一种将bondedProperty 变量更改为对象的简单方法。

之前:

this.bondedProperty = 10;

之后:

this.bondedProperty =  'value': 10 ;

这样,如果其中的值相同,更改检测将捕获您的更新事件。

StackBlitz DEMO

【讨论】:

是的,因为'你传递了一个不同的值,一个文字对象,尽管它具有相同的属性,但它是一个新对象,在内存中有另一个地址。 正确,这适合你吗? 不,但可以帮助某人理解它的工作原理。

以上是关于Angular 2 - 检测绑定属性何时收到值的主要内容,如果未能解决你的问题,请参考以下文章

Angular Cdk步进器,如何检测何时添加了新步骤

Angular 1.6.4如何检测组件的无绑定属性的变化[重复]

ngOnChanges无法检测数组内容修改时解决方案

检测具有相同名称但不同值的 Angular 绑定的更改?

Angular 2 Material:无法绑定到“值”,因为它不是“md-radio-button”的已知属性

Angular2绑定属性值