2

I have created a method and attached it to ngClass for adding two styles depending upon the condition.I am also passing the number as parameter to be used in the switch case.

component.html

<div class="circle" [ngClass]="setMyClassesCircle(1)">
<div class="circle" [ngClass]="setMyClassesCircle(2)">
<div class="circle" [ngClass]="setMyClassesCircle(3)">
<div class="circle" [ngClass]="setMyClassesCircle(4)">

component.ts

 setMyClassesCircle(val)
 {
   let circleClasses
   console.log('Inside method')

   switch(val)
   {

     case 1:
     {

    circleClasses = {
   'inprogress-circle': this.inProgress == val,
   'completed-circle': this.oneCompleted == true

   } 
     break;
   }
   case 2:
   {
    circleClasses = {
   'inprogress-circle': this.inProgress == val,
   'completed-circle': this.twoCompleted == true
   } 
     break;
   }
   case 3:
   {
    circleClasses = {
   'inprogress-circle': this.inProgress == val,
   'completed-circle': this.threeCompleted == true
   } 
     break;
   }
   case 4:
   {
    circleClasses = {
   'inprogress-circle': this.inProgress == val,
   'completed-circle': this.fourCompleted == true
   } 
     break;
   }

Through this way I am binding circleClasses to my template.

But the issue I am facing is setMyClassesCircle() method is called more than 10 times, while I am calling the method only four times.'Inside method' is printed more than 10 times in my console.

I could not figure out why the method is being called these many number of times.

Sathya Narayanan GVK
  • 849
  • 2
  • 16
  • 32
  • That is excpected. You are using a method in a template, and that method will be called for each detected change. – John May 28 '19 at 06:18
  • a demo code over stackblitz.com would be more helpful as per your doubt in comment section of Ehsan Kiani's answer – Shashank Vivek May 28 '19 at 06:50

3 Answers3

3

I think it called many times because of angular change detection, the cleaner solution is to use ngclass in-line like this:

    <div class="circle" [ngClass]="{
        'inprogress-circle': inProgress == 1,
       'completed-circle': oneCompleted == true }" >

 <div class="circle" [ngClass]="{
        'inprogress-circle': inProgress == 2,
       'completed-circle': oneCompleted == true }" >

 <div class="circle" [ngClass]="{
        'inprogress-circle': inProgress == 3,
       'completed-circle': oneCompleted == true }" >

 <div class="circle" [ngClass]="{
        'inprogress-circle': inProgress == 4,
       'completed-circle': oneCompleted == true }" >
Ehsan Kiani
  • 3,050
  • 1
  • 17
  • 19
  • this is not an exact solution as the question also has a condition depending on `1` , `2` ... and so on – Shashank Vivek May 28 '19 at 06:20
  • The question has only 4 condition as you can see in switch block, let the op decide – Ehsan Kiani May 28 '19 at 06:24
  • Thanks for the answer..little bit more on this..can you suggest me a way to change the property value that is being declared inside the class but have bee changed based on a condition in ngOnInit..That updated value should be taken by the view – Sathya Narayanan GVK May 28 '19 at 06:36
  • I'm sorry but can you explain a little more – Ehsan Kiani May 28 '19 at 06:39
  • yes...For example i am getting @input() inProgress in my component...I am changing its value based on condition in ngOnInit..But the changes does not get reflected in my view..I have even tried ngAfterViewInit..But the initial value recieved remains the same in the template – Sathya Narayanan GVK May 28 '19 at 06:43
  • @Sathyanarayanan maybe if you put quote over the value it'll work like this inProgress == '1' – Ehsan Kiani May 28 '19 at 06:49
  • https://stackblitz.com/edit/angular-mbazwq In this example i have test property decalred as 5..But i am changing its value in ngOnInit..But the updated value does not relfect in the view – Sathya Narayanan GVK May 28 '19 at 07:00
  • 1
    @Sathyanarayanan that's because you don't bind the number, change it like this – Ehsan Kiani May 28 '19 at 07:06
  • Upto the moment i had an assumption that only if i am passing a property to the child component i should have the square brackets on..Anywayss thanks for the support ! – Sathya Narayanan GVK May 28 '19 at 07:10
1

Angular runs changedetection life cycle several times to determine if the outcome of your function has changed. It'll run it every time you click things or similar events happen to determine if things have changed again. Binding values to functions is not advised for this reason, instead you should calculate the values in your .ts file and just bind against the precalculated values.

Andreas Turku
  • 438
  • 3
  • 9
  • I need my property values to be changed based on a condition in my ngOnInit.But my view is not updating to the latest value.I have tried ngAfterViewInit too – Sathya Narayanan GVK May 28 '19 at 06:22
  • How can i precalculate values before it reaches the template.For Example: I have declared myVar = 5 and I want to change based on a condition before it reaches the template.Thanks for the help – Sathya Narayanan GVK May 28 '19 at 06:24
1

There have been four node “Div” inside DOM, so each node called at least one time & each time your method returning different value which again raise 4 times.

Like this would be your seq:

1st Detect Change – Method called –4 Times. 2nd Detect Change – Method called –4 Times. 3rd Detect Change – Method called –4 Times. 4th Detect Change – Method called –4 Times. So, over all your method should be called 16 times if there are 4 nodes. Try to remove 1-Node, and your method should be called 4 X 3= 12 Times. This is how Angular works!!