0

I'm using a child component to build a complex object consisting of recursive child arrays and objects. I'd like a way to get access to this object in the parent component using live binding.

Values within the object change based on user input (select boxes, inputs etc.), so I need a way to emit the @Output() EventEmitter and pass the entire object whenever one if it's properties change.

Any ideas on how to accomplish this or is there another route I can take?

See some concept code below, in which the input has two-way data binding to a deep value in the complex object, and I need to emit this change to a parent by detecting the change somehow.

The actual form is more complex, so I'd like to avoid using specific events like watching for a change in each of the inputs to manually trigger the event emitter if possible.

Parent template:

<child-component (emitter)="emitterHandler($event)"></child-component>

Parent component:

emitterHandler(obj){ console.log(obj); }

Child component:

@Output() emitter: EventEmitter<any> = new EventEmitter();    
complexObj = {data: 'test', lines: [{data: 'asd', time: 123},{data: 'xcv', time: 233}]};

Child template:

<input [(ngModel)]="complexObj.lines[0].data"></input>
NJ.
  • 7,486
  • 1
  • 19
  • 20
  • 1
    you can emit eventemitter on change of your input `` – JayDeeEss Oct 18 '17 at 13:37
  • Thanks for the suggestion. The form is a little more complex than illustrated with lots of potential inputs. It would be a shame to have to use on change detection for each of the inputs. Is there any other way? – NJ. Oct 18 '17 at 13:39

1 Answers1

4

You can use valueChanges of the NgForm :

Component

@ViewChild('myForm') myForm: NgForm;

// this will be called when any input inside the form changes
this.myForm.valueChanges.subscribe(val => {
    // emit the event
});

Template

<form #myForm='ngForm' ...>
    // your select , input or nany form elements
</form>

Above code is for template driven form,

Here is the article for data-driven form on this : https://alligator.io/angular/reactive-forms-valuechanges/


Nice way to go is :

this.myForm.statusChanges.subscribe(res => {
    if (res === 'VALID') {
       // emit(this.myForm.values)
    }
});

This will emit the values when the data is valid, and in above code, no matter values is right or wrong it will fire the event.

Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
  • Thanks for the suggestion. I'm going to try it out. The child component actually consists of a bunch of recursion, with children creating children of the same type etc. Is there anyway good way to conditionally wrap the top level component in the
    tags so I can access all the possible child inputs?
    – NJ. Oct 18 '17 at 22:16
  • e.g. Child template might have: (and recursively create more inputs this way), if I wrap the entire thing in a form tags, I will have nested forms – NJ. Oct 18 '17 at 22:18
  • this wont work on nested component ? as ngForm is also not able to get values from nested inputs. – Vivek Doshi Oct 23 '17 at 04:17