0

I've split up my components into sub components to try and get resuability out of certain components. One of my components has been split 3 components, and now they are being used as nested child components :

Page component (with a service)
- Widget component (Passing in an object using @Input)
  -Settings component (Passing in an Object using @Input with getter/setter and EventEmitter)
   - General Settings component (Passing in a variable of type string from the parent object using @Input with getter/setter and EventEmitter)
    -Input (bound using ngModel)

The following stackblitz is from the following stackoverflow question.

In my specific project what I'm finding is that using getters/setters to do the two way binding down the chain of components is very heavy to the point that the browser window needs to be closed.

From trying to investigate the problem I've noticed that when I alter the value in the input field, the getters continuously get fired. You can see this when you add a console.log in the get block.

My question is whether there is a way to overcome this, or have I mis-interpreted the way that two way databinding in custom components should work ?

NB: I tried to use the Performance tab in Chrome's development console, but I didn't know how to interpret the results. Coming to the conclusion that it has something to do with the getter being called continuously is just from trial and error.

user3836415
  • 952
  • 1
  • 10
  • 25
  • I have been playing with heaps of getters and setters and had no performance issues at all. https://stackblitz.com/edit/angular-hvgcys my forms and my table https://stackblitz.com/edit/angular-7ahmqw – Adrian Brand Mar 28 '19 at 04:14
  • In stackblitz.com/edit/angular-hvgcys in the directive, I placed a console.log in the getter and noticed that it is continuously being executed. I'm assuming that you haven't seen performance issues from this ? – user3836415 Mar 28 '19 at 04:28
  • It all depends on what that getter does, if it just returns a value then no, if you are running logic then it will have a performance hit. – Adrian Brand Mar 28 '19 at 04:29
  • I've altered my code to pass the variable directly to the component using a service and my performance issues disappeared. I'm only guessing that this is due to the getter/setter method at this stage. – user3836415 Mar 28 '19 at 04:30
  • The getter for me is just returning the value as you have it. no additional logic. – user3836415 Mar 28 '19 at 04:30

1 Answers1

0

Your problem is because you are firing the event emmitter inside the setter, you have created a two way binding feedback loop.

The event emitter updates the parent component and the new value is fed back into the setter.

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
  • Isn't that what you are supposed to do ? I haven't got my head around the get/set and event emiter but the examples that I've seen - which don't provide an explanation is stating this is the method (e.g https://blog.angulartraining.com/tutorial-create-your-own-two-way-data-binding-in-angular-46487650ea82) – user3836415 Mar 28 '19 at 04:45
  • The setter with the input should be used to update your private member variable but should not fire the event emitter. That notifies the parent component of a change, so you are now in a loop of parent sends data down, the child notifies parent of change and you are in a loop. When you have changes locally in the child you update the local member variable and then fire the event emitter. – Adrian Brand Mar 28 '19 at 04:49
  • So does that mean I need to add in a keyup/keydown or onmodelchange function to fire the event ? Most of the articles have examples of a button click? – user3836415 Mar 28 '19 at 22:36