【问题标题】:Angular 2: Binding to Functions from Component TemplatesAngular 2:从组件模板绑定到函数
【发布时间】:2016-10-07 20:19:51
【问题描述】:

在 Angular 1 中,我们避免过多地从模板表达式中调用函数,例如ng-repeat="item in vm.getFilteredItems()" 因为与 getFilteredItems 的结果无关的属性更改会导致函数在摘要上重复且不必要地重新计算,这通常会导致大规模的性能问题。相反,我们绑定到对象,并根据事件进行计算(例如ng-repeat="item in vm.filteredItems)。

在 Angular 2 中,脏检查过程已经过优化,但组件模板中调用的函数仍然会在组件级别的任何属性发生更改时被调用,无论该函数是否依赖于这些属性。如果使用不当,我预计这可能会导致相同的性能问题。

这是 Angular 2 中不同方法的简化示例:

// function binding in template
@Component({
  selector: 'func',
  template: `
    <input [(ngModel)]="searchTerm" placeholder="searchTerm" />
    <div *ngFor="let name of filteredNames(searchTerm)">{{name}}</div>
  `
})
export class FuncComponent {
  @Input() names:string[];

  filteredNames(searchTerm) {

    if (!searchTerm) return this.names;

    let filteredNames = [];

    return this.names.filter((name) => {
      return name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
    });
  }
}

-

// no function binding
@Component({
  selector: 'nofunc',
  template: `
    <input [(ngModel)]="searchTerm" (ngModelChange)="search($event)" placeholder="searchTerm" />
    <div *ngFor="let name of filteredNames">{{name}}</div>
  `
})
export class NoFuncComponent implements OnInit {
  @Input() names:string[];

  searchTerm: string;

  ngOnInit() {
    this.search(this.searchTerm);
  }

  search() {
    if (!this.searchTerm) {
      this.filteredNames = this.names;
      return;
    }

    this.filteredNames = this.names.filter((name) => {
      return name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) > -1;
    });
  }
}

http://plnkr.co/edit/AAFknlJgso3D8F1w3QC1?p=preview

在 Angular 2 中这仍然是一个问题吗?首选哪种方法,为什么?谢谢!

【问题讨论】:

    标签: angularjs angular


    【解决方案1】:

    你可以创建一个管道。管道(如果 pure)仅在依赖值更改时才被调用。

    @Pipe({
      name: 'search',
    //  pure: 'false'
    })
    class SearchPipe {
      transform(names, searchTerm) {
       if (!this.searchTerm) {
          this.filteredNames = names;
          return;
        }
    
        return names.filter((name) => {
          return name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) > -1;
        });
      }
    }
    
    @Component({
      selector: 'func',
      pipes: [SearchPipe],
      template: `
        <input [(ngModel)]="searchTerm" placeholder="searchTerm" />
        <div *ngFor="let name of names | search:searchTerm">{{name}}</div>
      `
    })
    export class FuncComponent {
      @Input() names:string[];
    }
    

    如果管道需要识别 names 中的更改,则需要禁用 pure

    如果 names 被不同的实例替换,而不仅仅是添加或删除成员,则 pure 工作正常,并且管道仅在 namessearchTerm 更改时执行。

    提示

    devMode(默认)中,变更检测运行两次,管道的调用次数将是预期的两倍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-03
      • 2018-11-27
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多