Referring to Angular2 documentation file here: [https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter] (Parent to child setter), I have the following child component code:
import { Component, Input } from '@angular/core';
@Component({
selector: 'name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent {
private _name = '';
@Input()
set name(name: string) {
console.log("name change");
this._name = name;
}
get name(): string { return this._name; }
}
And the parent is simple:
import { Component } from '@angular/core';
@Component({
selector: 'name-parent',
template: `
<h2>Parent </h2>
<name-child [name]="name"></name-child>
`
})
export class NameParentComponent {
// somewhere on ngOnInit, set name without changing value
ngOnInit() {
// get pending paged only and so on
setTimeout(() => {
this.name = "a";
setTimeout(() => {
this.name = "a";
setTimeout(() => {
this.name = "a";
},1000);
},1000);
},1000);
}
}
You'd expect the console to log out "name change" three times in 3 seconds. It doesn't, it logs it once, and ignores subsequent sets (this happens only if the value does not change). How can I make the input pick up the set event, regardless of whether value changed or not?
Use the ngOnChanges() lifecycle method in your component. ngOnChanges is called right after the data-bound properties have been checked and before view and content children are checked if at least one of them has changed.
If you click on the “set to Parent” button multiple times, the child component setter won't be triggered from 2nd time onward. Thus it looks like the Input setter is only being fired once if the value of the setter hasn't been changed.
1. Using the ngOnChanges() lifecycle method. **ngOnChanges **method gets called when any input values changes happen in the Component. This method has a **SimpleChanges **object from which we can compare current and previous values.
The article you give explicitly says
Intercept input property changes with a setter
when what you are trying to achieve is not about tracking changes at all. It is about sending an event from parent to child and this is where RX Subject
(any of 4 of them) or Angular2 EventEmitter
is really good.
You can create one of them in the parent and pass it to the child. Then, after you subscribe to it, you can track all the events regardless of the value.
I see two ways to solve it:
1) Use immutable value
setTimeout(() => {
this.name = new String("a");
setTimeout(() => {
this.name = new String("a");
setTimeout(() => {
this.name = new String("a");
}, 1000);
}, 1000);
}, 1000);
2) Change input property directly
@ViewChild(NameChildComponent) child: NameChildComponent;
setTimeout(() => {
this.child.name = "a";
setTimeout(() => {
this.child.name = "a";
setTimeout(() => {
this.child.name = "a";
}, 1000);
}, 1000);
}, 1000);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With