2016-06-07 4 views
8

In Angular 1 abbiamo evitato di chiamare le funzioni da espressioni di modello eccessive, ad es. ng-repeat="item in vm.getFilteredItems()" poiché le modifiche delle proprietà non correlate al risultato di getFilteredItems causerebbero la ricalcola ripetutamente e inutilmente dei digest, il che generalmente causa problemi di prestazioni su larga scala. Invece ci siamo legati agli oggetti e calcoliamo in base agli eventi (ad esempio ng-repeat="item in vm.filteredItems).Angolare 2: collegamento a funzioni da modelli di componenti

In Angular 2, il processo di controllo sporco è stato ottimizzato, ma le funzioni richiamate nei modelli di componenti saranno ancora chiamate quando si modificano le proprietà a livello di componente, indipendentemente dal fatto che la funzione dipenda da tali proprietà. Mi aspetto che ciò potrebbe comportare gli stessi problemi di prestazioni se usato in modo improprio.

Ecco un esempio semplificato dei diversi approcci in angolare 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

È ancora una preoccupazione in angolare 2? Quale approccio è preferito e perché? Grazie!

risposta

5

È possibile creare una pipe. I tubi (se pure) vengono chiamati solo quando cambiano i valori dipendenti.

@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[]; 
} 

Se il tubo deve riconoscere variazioni di names poi pure deve essere disabilitato.

Se names è sostituito da un diverso esempio, invece di soli membri aggiunti o rimossi, quindi pure funziona bene e il tubo viene eseguita solo se names o searchTerm modifiche.

Suggerimento

In devMode (default) il rilevamento delle modifiche corre due volte e il tubo si chiamerà il doppio di quanto previsto.