最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

The most optimized way to bind variables in Angular when dealing with objects - Stack Overflow

programmeradmin1浏览0评论

I read the manual of binding object properties in Angular, however I struggle to find the perfect most optimized solution.

Let's say i have a model User

export class User {
  public _id: number;
  public _firstName: string;
  public _lastName: string;
  public _active: boolean;
  public _type: string;

  constructor(id: number, firstName: string, lastName: string, type: string, active: boolean = true) {
    this._id = id;
    this._firstName = firstName;
    this._lastName = lastName;
    this._active = active;
    this._type = type;
  }
}

I want to display ID, firstName and LastName if the user is active and of certain type - let's say administrator. Pretty simple, right?

From what I've read the easiest solution is:

<span *ngIf="model._active && model._type === 'administrator'">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model._type}}</span>

You can even pipe this:

<span *ngIf="model._active | isModelActive : model._type">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model._type}}</span>

Pipe gets called only once on init, and each time if property "active" changes. Changing the property "id" doesn't call the pipe.

In reality however your models most likely have private fields with accessors, since you want to encapsulate your objects. Now this is when this goes badly really quick.

private _active: boolean;
get active(): boolean {
   console.log('get active');
   return this._active;
}

now binding the getter instead of field causes this function to be called multiple times, plus it also gets called when other properties are changed (like id for example). God forbid if you have (mouseover) somewhere else because it will constantly redraw the view.

You can also pipe this:

<span *ngIf="model.active | isModelActive : model.type">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model.type}}</span>

But still changing the property "id" causes the redraw. And if you want to pass the object to the pipe, you have to declare it impure, which according to documentation can cause serious performance degradation.

So which solution is the best? Or maybe there is another one I don't know about. Lemme know.

I read the manual of binding object properties in Angular, however I struggle to find the perfect most optimized solution.

Let's say i have a model User

export class User {
  public _id: number;
  public _firstName: string;
  public _lastName: string;
  public _active: boolean;
  public _type: string;

  constructor(id: number, firstName: string, lastName: string, type: string, active: boolean = true) {
    this._id = id;
    this._firstName = firstName;
    this._lastName = lastName;
    this._active = active;
    this._type = type;
  }
}

I want to display ID, firstName and LastName if the user is active and of certain type - let's say administrator. Pretty simple, right?

From what I've read the easiest solution is:

<span *ngIf="model._active && model._type === 'administrator'">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model._type}}</span>

You can even pipe this:

<span *ngIf="model._active | isModelActive : model._type">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model._type}}</span>

Pipe gets called only once on init, and each time if property "active" changes. Changing the property "id" doesn't call the pipe.

In reality however your models most likely have private fields with accessors, since you want to encapsulate your objects. Now this is when this goes badly really quick.

private _active: boolean;
get active(): boolean {
   console.log('get active');
   return this._active;
}

now binding the getter instead of field causes this function to be called multiple times, plus it also gets called when other properties are changed (like id for example). God forbid if you have (mouseover) somewhere else because it will constantly redraw the view.

You can also pipe this:

<span *ngIf="model.active | isModelActive : model.type">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model.type}}</span>

But still changing the property "id" causes the redraw. And if you want to pass the object to the pipe, you have to declare it impure, which according to documentation can cause serious performance degradation.

So which solution is the best? Or maybe there is another one I don't know about. Lemme know.

Share Improve this question asked Jan 29 at 10:45 user1108011user1108011 213 bronze badges 3
  • angular version? – Naren Murali Commented Jan 29 at 10:59
  • pass the whole object as input to pipe and do not make it impure, but you need not to mutate the object if you want to update the object then you will have to make something like this: this.model = { ...this.model, id: newId } as by default pure pipe make memoization if the inputs are the same not changed so by passing the object you need with every change to make new object as it will detect that the refrence of the object changed so will execute the pipe – Ahmed Elhakim Commented Jan 29 at 12:03
  • Angular CLI: 13.3.10 Ok, so from what I understand you can pass object to pure pipe, but object has to be Immutable -> every edit has to create a new object. Only then new reference is created which can be picked up by a pipe. – user1108011 Commented Jan 29 at 14:17
Add a comment  | 

1 Answer 1

Reset to default 0
  1. Using get method is not slower than field ref, so this should not bother u. If while mouseover this get method will return same result, view wont be redrawn.
  2. Pipe. Pure pipe wont run when you change id, but it will check that pipe inputs did not change each digest cycle. So it wont be faster than ngIf

You should not focus on things above in 99.9999% of cases -- you will never get any measurable performance improvement.

  1. ChangeDetectionStrategy. This is what you missed. If you care about performance you should use ChangeDetectionStrategy.OnPush. E.g. with onPush get-methods, pipes etc. will be called less frequently.
发布评论

评论列表(0)

  1. 暂无评论