Skip to content Skip to sidebar Skip to footer

Angular Two-Way Data Binding And Watching For Changes In Parent Component

It seems there is no way to watch changes in the parent component when using two-way data binding. I have a custom input component for collecting a tag list. Two-way data binding i

Solution 1:

When you implement a two way binding of your own, you have to implement an event Emitter. The syntax for that is mandatory.

this means that you have a hook to listen to if the value changes.

Here is a demo :

<hello [(name)]="name" (nameChange)="doSomething()"></hello>
_name: string;
@Output() nameChange = new EventEmitter();

set name(val) {
  this._name = val;
  this.nameChange.emit(this._name);
}

@Input()
get name() {
  return this._name;
}

counter = 0;

ngOnInit() {
  setInterval(() => {
    this.name = this.name + ', ' + this.counter++;
  }, 1000);
}

Stackblitz

From what I know, this seems the less annoying way to use it, and any two way binding will follow the same rule no matter what, i.e. it ends with the Change word !


Solution 2:

Your implementation is actually not two-way databinding, the parent and child component are just sharing a reference on the same skillTags variable.

The syntax [(tags)]='skillTags' is syntaxic sugar for [tags]='skillTags' (tagsChange)='skillTags = $event'

You need to implement tagsChange in the child component like this: @Output('tagsChange') tagsChange = new EventEmitter<any>();, then any time you want to modify tags into the children component, dont do it directly, but use this.tagsChange.emit(newValue) instead.

At this point, you'll have real two-way databinding and the parent component is the unique owner of the variable (responsible for applying changes on it and broadcasting changes to the children).

Now in your parent component, if you want to do more than skillTags = $event (implicitly done with [(tags)]='skillTags'), then just add another listener with (tagsChange)='someFunction($event)'.

StackBlitz Demo


Solution 3:

Don't know if this is what you're looking for, but have you tried using @Input()?

In child component

@Input() set variableName(value: valueType) {
  console.log(value);
}

In parent component

<input-tags formControlName="skillField" [(tags)]='skillTags'
[variableName]="skillTagUpdate($event)"></input-tags>

The input function is called every time the object binded to the function is changed.


Solution 4:

you could listen to the change:

<input-tags formControlName="skillField" [tags]='skillTags' (tagsChange)='skillTags=$event; skillTagUpdate();'></input-tags>

or use getter and setter:

get skillTags(): string {
    return ...
}
set skillTags(value) {
    variable = value;
}

another approach:

 export class Test implements DoCheck {
  differ: KeyValueDiffer<string, any>;
  public skillTags: string[] = [];
  ngDoCheck() {
    const change = this.differ.diff(this.skillTags);
    if (change) {
      change.forEachChangedItem(item => {
        doSomething();
      });
    }
  }
  constructor(private differs: KeyValueDiffers) {
    this.differ = this.differs.find({}).create();
  }
}}

Solution 5:

1.you can use output(eventemitter)

2.easiest solution is rxjs/subject. it can be observer and observable in same time

Usage:

1.Create Subject Property in service:

import { Subject } from 'rxjs';

export class AuthService {
   loginAccures: Subject<boolean> = new Subject<boolean>();
}

2.When event happend in child page/component use :

logout(){
  this.authService.loginAccures.next(false);
}

3.And subscribe to subject in parent page/component:

constructor(private authService: AuthService) {
    this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {this.isLoggedIn = isLoggedIn;})
}

Update

for two-way binding you can use viewchild to access to your child component items and properties

<input-tags #test></<input-tags>

and in ts file

  @ViewChild('test') inputTagsComponent : InputTagsComponent;

save()
{
   var childModel = this.inputTagsComponent.Model;
}

Post a Comment for "Angular Two-Way Data Binding And Watching For Changes In Parent Component"