Home > Blockchain >  With Angular properties shouldn't they be private and accessed via methods?
With Angular properties shouldn't they be private and accessed via methods?

Time:04-14

I'm getting a bit confused with Angular/Typescripting here. I thought that properties are to be kept hidden to prevent any possible external alteration to a properties value.

For example:

export class Foo{
  private _bar: string;

  constructor(private bar: string){
    this._bar = bar;
  }

  public get bindBar(): string {
      return this._bar;
  }
}

And some template

<span>{{ bindBar }}</span>

But in reading there are performance issues with having binding to a method from the html template as methods get called under every change detection that occurs on the page.

Options that I am seeing are to either make it a public property or to use Pipes.

Pipes just seem like overkill to have to implement for every property in a page that you need to bind and public vars have almost always been a no no.

I cannot find any clear direction on the Angular website on how to implement binding and not have a negative impact on performance but also this pipe thing just does not seem the right way of doing it.

Can someone explain?


Thank you for the links to other articles. In them I found an example of the triggering method calls and branched the example to test if it was component based or contained within a component.

As you can see in the example it is not bound to a component as the events triggered affect the other components. My Stackblitz 2 component test

CodePudding user response:

In typescript, it is mostly safe to use public variables, and accessing them directly. When binding, things tend to go sideways when using methods, so it is recommended to use variables in your bindings.

CodePudding user response:

This getter

  public get bindBar(): string {
      return this._bar;
  }

is not going to degrade the performance of your application. Calling this takes roughly the same amount of time as directly referencing the variable. All the variables in your template also get referenced at every change detection, to check if they've changed. So calling this in your template is no different than referencing a public variable.

That being said, if you want to make a variable read only, you can just use the readonly keyword.

readonly bar: string;

Don't believe me? Here's a test:

https://stackblitz.com/edit/angular-ivy-zgjwnw?file=src/app/app.component.ts

Over one million change detection cycles, both strategies take roughly 650 milliseconds with my hardware.


The only time you need to be worried about calling methods during change detection is if those methods take a significant amount of time, or if you're making requests to an API. Never put those sort of method calls in your template unless you're tying them to an event.

If you're worried about performance, you should be more concerned with how many times change detection actually fires, and how many components get checked each time. The default change detection strategy is to check every single variable and method call in all current component templates on every action that might have changed something.

The OnPush change detection strategy lets you change when component templates get checked, and the ChangeDetectorRef.detach() service method lets you completely detach the component from being checked automatically.

This is a great article for more info:

https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/


I highly recommend putting a breakpoint right before calling ChangeDetectorRef.detectChanges() and walking through a change detection cycle in the debugger. You'll see that the change detector saves the last value of any interpolated values in the template (whether they're a property or the result of a method call) in an object called lView (last view). Then on a change detection cycle it recalculates those interpolated values again - whether that means referencing a variable or calling a method. If any of the values differ then the change detector will reference the associated html node and change it's value.

In the context of pipes, the change detector will check the input value and only call the pipe if that value has changed. That's because pipes are assumed to be pure functions (output only relies on input). So if you're calling a time consuming pure method, it's more efficient to make it a pipe. Examples: formatting a string, performing validation, math equations, deep comparisons, etc.

  • Related