reza
reza

Reputation: 6358

PrimeNg button: how to set the disabled state in html

So I have setup a primeng button to set the disable/able state by calling a function...

The html is

<div>
<form name="searchForm" role="form">
    <div class="form-group">
        <location-tree
                (selectedLocationsE) = locationChangeHandler($event)
        ></location-tree>
        <br/>
    </div>
    <div class="form-group">
        <units
                (selectedUnitsE) = unitChangeHandler($event)
                [locationsI]="locations"
        ></units>
        <br/>
    </div>
    <div class="form-group">
        <bundles></bundles>
        <br/>
    </div>
    <div class="form-group">
        <time-range></time-range>
        <br/>
    </div>
    <br/>
    <div>
        <button
                pButton type="button" [disabled]="disabled() == true" (click)="run()" label="Query"></button>
        Metric constant
    </div>
</form>

the function is

    disabled() {
    console.log('disabled?');
    return true;
}

the other components are all primeng dropdowns.

It all works ok but the disabled call is made every time there is any interaction with the any of the dropdowns. Many many calls...

Any thoughts on how I have set this up incorrectly?

Upvotes: 3

Views: 25333

Answers (1)

LarsMonty
LarsMonty

Reputation: 762

This is happening as a result of Angular's change detection algorithm. Here is what is going on:

The target [disabled] is bound to the result of the expression disabled() == true.

Every time an Angular change detection cycle runs (which is often), Angular wants to make sure that no bindings have changed. Therefore, it reevaluates the disabled() == true expression. This causes this function to run on every cycle, and this is why you are seeing so many function calls.

Here's the thing, this is how Angular is supposed to work. If you write a function in a binding, you are forcing Angular to call this function every cycle. Possible things you can do are:

  • Bind to a class variable instead of an expression including a function. e.g. some variable like private disabled : boolean. In this instance, Angular will only re-evaluate the binding every time disabled changes. Then you can use other functions to change the state of disabled, which will change the button.
  • If necessary, leave it as is! In your case, it's likely better to bind to a class variable, but it's not that expensive to run a small function like this every cycle.

Upvotes: 4

Related Questions