2017-07-21 3 views
0

In meiner AngularJS App habe ich die folgenden in meinem HTML-Templates zu tun:Angular2/4 ngFor Richtlinie nicht erlaubt variable Zuordnung

<tr ng-repeat="user in filtered = (users | filter:searchTerm | orderBy:firstName)"> 

Dann so konnte ich die Variable "gefiltert" in meinem Controller verwenden, dass ich hatte Zugriff auf meine gefilterten Tabellenzeilenelemente.

Angular 2/4 lässt diese Zuweisung nicht zu, also wie würde ich das in Angular 2/4 tun können?

UPDATE:

Komponente:

export class UsersComponent implements OnInit { 
    users = []; 
    totalItems = 0; 
    filteredUsers = []; 
    filteredUser: User; 

    constructor(private dataService: DataService) { } 

    ngOnInit() { 
    this.dataService.getUsers() 
    .subscribe(
     (data: any) => { 
     this.users = data.data; 
     }, 
     msg => console.error(`Error: ${msg.status} ${msg.statusText}`) 
    ); 
    } 

    trackItems(index, item){ 
    this.totalItems = index+1; 
    this.filteredUsers.push(item); // <- This does not work? Should be able to push the item to my filteredUsers array? 
    return item ? item.id : undefined; 
    } 
} 

Vorlage:

<tr *ngFor="let user of users | filterBy: ['firstName', 'lastName', 'email']: searchTerm; trackBy: trackItems"> 

Fehlermeldung:

UsersComponent.html:49 ERROR TypeError: Cannot read property 'push' of undefined 
    at DefaultIterableDiffer.webpackJsonp.../../../../../src/app/pages/users/users.component.ts.UsersComponent.trackItems [as _trackByFn] (users.component.ts:108) 
    at DefaultIterableDiffer.webpackJsonp.../../../core/@angular/core.es5.js.DefaultIterableDiffer.check (core.es5.js:6857) 
    at DefaultIterableDiffer.webpackJsonp.../../../core/@angular/core.es5.js.DefaultIterableDiffer.diff (core.es5.js:6830) 
    at NgForOf.webpackJsonp.../../../common/@angular/common.es5.js.NgForOf.ngDoCheck (common.es5.js:1669) 
    at checkAndUpdateDirectiveInline (core.es5.js:10837) 
    at checkAndUpdateNodeInline (core.es5.js:12330) 
    at checkAndUpdateNode (core.es5.js:12269) 
    at debugCheckAndUpdateNode (core.es5.js:13130) 
    at debugCheckDirectivesFn (core.es5.js:13071) 
    at Object.View_UsersComponent_0._co [as updateDirectives] (UsersComponent.html:58) 

UsersComponent.html:49 ERROR CONTEXT DebugContext_ {view: Object, nodeIndex: 97, nodeDef: Object, elDef: Object, elView: Object} 

Antwort

0
<tr *ngFor="let hero of heroes; let first = first; let last = last" > 
//OR 
<tr *ngFor="let hero of heroes; let even = even; let odd = odd" > 

//OR 
<tr *ngFor="let hero of heroes; trackBy: trackHero" > 

Wir können unseren eigenen Mechanismus zum Verfolgen von Elementen in einer Liste bereitstellen, indem Sie trackBy verwenden. Wir brauchen eine Funktion trackBy passieren, und die Funktion dauert ein paar Argumente, die ein Index und das aktuelle Element sind:

@Component({ 
    selector:'heroes', 
    template: ` 
    <table> 
     <thead> 
      <th>Name</th> 
     </thead> 
     <tbody> 
      <tr *ngFor="let hero of heroes; trackBy: trackHero" > 
       <td>{{hero.name}}</td> 
      </tr> 
     </tbody> 
    </table> 
` 
}) 
export class Heroes { 

    heroes = HEROES; 

    trackHero(index, hero) { 
     console.log(hero); 
     return hero ? hero.id : undefined; 

    } 


} 

http://blog.angular-university.io/angular-2-ngfor/

+0

Vielen Dank! Ein zusätzlicher Fehler, den ich bekomme. Ich kann das Element nicht in ein Array in meiner Komponente innerhalb der Funktion trackHero schieben. Wenn ich versuche, auf eine Variable zuzugreifen, die ich in meiner Komponente in trackHero definiert habe, heißt es, dass sie nicht definiert ist? –

+0

Bitte fügen Sie den Code hinzu, um die Frage zu erklären, wenn Sie denken, dass die Antwort auf Punkt ist, also akzeptieren Sie bitte, anderen zu helfen. –

+0

@DavidFinch stellen Sie sicher, dass das Array, das Sie drücken, ist definiert, ich bin mir nicht sicher, wie Sie auf das Array zugreifen, möglicherweise ist es etwas im Zusammenhang mit Gültigkeitsbereich der Variablen –

0

Sie as mit *ngIf verwenden können:

<ng-container *ngIf="users | filterBy:[...] as filteredUsers"> 
    <tr *ngFor="let user of filteredUsers"> 

Aber das schafft eine "Variable" filteredUsers, die lokal in der Vorlage ist, und hat nichts mit dem "Controller" zu tun. (Beachten Sie auch, dass die Angular team recommends against filter and sort pipes.)

Sie können eine Controller-Eigenschaft nicht im Kontext eines Templates Ausdruck, wie in *ngFor oder *ngIf verwendet. Sie können es in einem Event-Handler gesetzt, aber das ist eine andere Situation:

<my-component (onToggle)="prop = !prop"> 

Im Allgemeinen ist es vorzuziehen, zu viel Logik in der Vorlage ohnehin zu setzen zu vermeiden, dass. Die Vorlage sollte sich auf das beschränken, was notwendig ist, um Pixel auf den Bildschirm zu bringen, die den Zustand des Controllers repräsentieren. Wenn Sie etwas berechnen oder etwas filtern müssen, tun Sie das im Controller.

+0

Vielen Dank torazaburo! Ich habe getan, wie Sie vorgeschlagen haben, entfernt das Rohr und gefiltert in meinem Controller statt. Funktioniert perfekt! –