简体   繁体   English

Model 绑定属性与 BehaviorSubject(对于 ChangeDetectionStrategy)

[英]Model Binding Property vs BehaviorSubject (For ChangeDetectionStrategy)

I am very undecided whether to use BehaviorSubject to bind data to html.我很犹豫是否使用 BehaviorSubject 将数据绑定到 html。 Below are two examples, the First sample binds normally, and the second one binds with "changeDetection: ChangeDetectionStrategy.OnPush" and "BehaviorSubject"下面是两个示例,第一个示例正常绑定,第二个示例与“changeDetection: ChangeDetectionStrategy.OnPush”和“BehaviorSubject”绑定

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

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

As seen in Console, The first method, (ChangeDetection is default and always running), it always calls setName function and logs "init", but in second method, setName is only calls when if $data is registered new value, because of "ChangeDetectionStrategy.OnPush" (dont need ChangeDetectorRef.detectChanges() because data$ already inited).如控制台中所见,第一种方法(ChangeDetection 是默认值并始终运行),它始终调用 setName function 并记录“init”,但在第二种方法中,setName 仅在 $data 注册新值时调用,因为“ ChangeDetectionStrategy.OnPush”(不需要 ChangeDetectorRef.detectChanges(),因为 data$ 已经启动)。

When should I use method 1 or method 2?什么时候应该使用方法一或方法二? Is there an important performance increase?是否有重要的性能提升?

For example, which method should I use to show 100 data on the table (can be delete from table)?例如,我应该使用哪种方法在表上显示 100 条数据(可以从表中删除)?

Which one should I use to lazy load messages (like an infinite scroll)?我应该使用哪一个来延迟加载消息(如无限滚动)?

When should I use the BehaviorSubject (when just I need Observable) or should I always use it to bind data?我应该什么时候使用 BehaviorSubject(当我只需要 Observable 时)还是应该始终使用它来绑定数据?

First of all, using setName() method in the template is bad practice because it runs in every change detection and creates performance issues.首先,在模板中使用setName()方法是不好的做法,因为它会在每次更改检测中运行并产生性能问题。 so you can avoid this with Pure pipes .所以你可以用Pure 管道避免这种情况。 if you use pure pipe and avoid using the method, the first approach is ok and works fine.如果您使用纯 pipe 并避免使用该方法,则第一种方法可以并且工作正常。

but you can use BehaviorSubject inside data services in order to share data in a reactive way between components and other services as well.但是您可以在数据服务中使用BehaviorSubject ,以便在组件和其他服务之间以反应方式共享数据。

but ChangeDetectionStrategy.OnPush helps you to prevent some presentational components to be rendered each time change detection runs.但是 ChangeDetectionStrategy.OnPush 可以帮助您防止在每次更改检测运行时呈现一些表示组件。 for example, if a data or input changes in parent component and you have lots of chid component that are not affected with this change you can use this approach to avoid this components to be rendered and increase performance of your app例如,如果父组件中的数据或输入发生更改,并且您有许多不受此更改影响的 chid 组件,您可以使用这种方法来避免渲染这些组件并提高应用程序的性能

 public data = [
    { Id: 1, Name: 'A', formatedName: '' },
    { Id: 2, Name: 'B', formatedName: '' },
  ];

  public setName(e: string) {
    console.log('init');
    return e + '-' + e;
  }

  ngOnInit() {
    this.data.map((item) => {
      item.formatedName = this.setName(item.Name);
      return item;
    });
  }

<div *ngFor="let item of data">
  <span [innerText]="item.Id"></span>
  <span>{{ item.formatedName }}</span>
</div>

but the best practice is to use pipe但最佳做法是使用 pipe

@Pipe({
  name: 'customName',
})
export class CustomNamePipe implements PipeTransform {
  transform(name: string): string {
    return name + '-' + name;
  }
}


<div *ngFor="let item of data">
  <span [innerText]="item.Id"></span>
  <span>{{ item.Name | customName }}</span>
</div>


https://stackblitz.com/edit/angular-ivy-ssvytn https://stackblitz.com/edit/angular-ivy-ssvytn

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM