How do you run a function on the result of NgFor in Angular2?

江枫思渺然 提交于 2019-12-23 21:18:20

问题


Consider a list of all of the users in your system:

  allUsers = {
    a: {name:'Adam',email:'adam@testco.com',level:'admin',group:'Owners'},
    b: {name:'Barbra',email:'Barbra@testco.com',level:'admin',group:'Owners'},
    c: {name:'Chris',email:'Chris@otherplace.net',level:'standard',group:'Managers'},
    d: {name:'Dennis',email:'dsmolek@showman.com',level:'standard',group:'Managers'},
    e: {name:'Elizabeth',email:'eadams@testco.com',level:'standard',group:'Staff'},
    f: {name:'fred',email:'fred@testco.com',level:'visitor',group:'Visitor'},

  }

Then a list of the users on a project:

usersList = ['a','b','d','f'];

So you have a nice easy function to take the user id and lookup the rest of the user details:

  getUser(userId){
    console.log('Getting User with Id:', userId);
    if(allUsers[userId]) return allUsers[userId];
  }

Then in the template you use *ngFor to loop through the users in the list, but you want to then lookup the full set of details

<tr *ngFor="#userId in usersList" #user="getUser(userId)">
  <td>{{user.name}}</td>
</tr>

Doesn't work... Without creating custom components or other more complex stuff I can't figure out how to run the getUser function once per user. I can of course run it over and over like:

<td>{{getUser(userId).name}}</td>

but this doesn't seem like the best way. Is there an easier way to get access to the userId variable and set it as a local variable?

Here's a plunker of what I've been playing with so far


回答1:


Though you can create a variable on ngFor template directive, but that variable can only take value of index, even, odd & last.

Thats why I could use pipe for this case, where you need to pass usersList & allUsers to custom @Pipe getUsers (it will act same as a filter in Angular1).

Markup

<tr *ngFor="let user of usersList | getUsers: allUsers">
  <td>
    {{user.name}}
  </td>
  <td>
    {{user.email}}
  </td>
  <td>
    {{user.level}}
  </td>
  <td>
    {{user.group}}
  </td>
</tr>

Code

@Pipe({
  name: 'getUsers',
  pure: false
})
export class GetUserPipe implements PipeTransform {
  constructor(){
    this.test = 'Test';
  }
  transform(array:Array<string>, object: any) : any {
    // for..in loop
    let output = [];
    for (var num in array)
    {
      // somehow object goes inner side
      output.push(object[0][array[num]]);
    }
    console.log(output)
    return output;
  }
}

Demo Plunkr




回答2:


I like

<td>{{getUser(userId).name}}</td>

That's what I would use. It is much easier than creating, say, a pipe/filter.

Even if you could do something with a local template variable, I believe it would get re-evaluated for every item in the list, every change detection cycle, just like the HTML shown above.

See also ng2: How to create variable in ngFor loop, where one of the suggestions is to create a child component, and pass getUser(userId) to an input property on that component.




回答3:


You can have your markup as follows

<tr *ngFor="theUser in getTheUsers(usersList)" >
   <td>{{theUser.name}}</td>
</tr>

getTheUsers() function should be something like this

getTheUsers(usersList:string[]){
  return usersList.map(user=> this.allUsers[user]); 
}


来源:https://stackoverflow.com/questions/35162539/how-do-you-run-a-function-on-the-result-of-ngfor-in-angular2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!