angular 2 添加新项目到列表时,自定义管道不重新排序列表
angular 2 when adding new item to list, custom pipe not reordering list
我实现了一个 orderby 管道,它在 DOM 加载时工作正常。但是当我向列表中添加一个新项目时,我的管道没有被激活,并且已添加到列表中的新项目不是顺序的 - 但添加到列表中的最后一个位置。
管道:
import { PipeTransform, Pipe } from '@angular/core';
import { ITeam } from './team';
@Pipe({
name: "LeagueFilter"
})
export class LeagueFilterPipe implements PipeTransform {
transform(value: any[], filterBy: string): any[] {
filterBy = filterBy ? filterBy.toLocaleLowerCase() : null
for (let i = 0; i < value.length - 1; i++) {
for (let j = 0; j < value.length - 1; j++) {
if (value[j][filterBy] < value[j + 1][filterBy]) {
let temp = value[j]
value[j] = value[j + 1]
value[j + 1] = temp
}
}
}
return value;
}
}
Html:
<div class="container">
<div class="row">
<div class="col-sm-offset-1 col-sm-4">
<h2>
{{leagueTable}}
</h2>
<table class="table table-responsive">
<thead>
<tr>
<th>#</th>
<th>Team</th>
<th>Points</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams | LeagueFilter:'points'; let i = index">
<td>{{i+1}}</td>
<td>{{team.name}}</td>
<td>{{team.points}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<fieldset class="col-sm-offset-1 col-lg-3">
<legend>Add Team</legend>
<label for="name">Name </label>
<input type="text" name="" value="" [(ngModel)] = "newTeam.name" />
<br/>
<label for="name">Points</label>
<input type="text" name="" value="" [(ngModel)] = "newTeam.points" />
<button type="submit" (click)="addTeam()">Add</button>
</fieldset>
</div>
</div>
组件:
import { Component } from '@angular/core';
import { ITeam } from './team';
@Component({
selector: 'league-list',
moduleId:module.id,
templateUrl: 'league-list.component.html',
styleUrls: ['league-list.component.css']
})
export class LeagueListComponent {
leagueTable: string = "La Liga"
teams: ITeam[] = [
{ name: "Barcelona", points: 84 },
{ name: "Real Madrid", points: 85 },
{ name: "Valencia", points: 78 },
{ name: "Sevilla", points: 80 },
{ name: "Villareal", points: 62 },
]
newTeam:ITeam = { name:"", points:null };
addTeam():void{
this.teams.push(this.newTeam)
}
}
管道仅在值更改时由 Angular 执行(或管道参数,如果有的话)
您的示例中没有参数,值也没有改变。 Angulars 变化检测不检查数组的内容,仅当引用发生变化时(到不同的数组实例,对象相同。顺便说一句。)
你能做什么
- 使管道不纯净
@Pipe({
name: "LeagueFilter",
pure: false
})
这样管道将在每次更改检测时执行 运行,这可能会变得昂贵。管道应该注意不要做不必要的工作,例如缓存结果并使用 IterableDiffer
(就像在 NgFor
中使用的那样)来显式检查数组的变化。
- 修改后创建数组副本
this.teams.push(this.newTeam);
this.teams = this.teams.slice();
如果数组很大并且经常发生变化,这也会变得昂贵
- 引入一个人工管道参数
this.teams.push(this.newTeam);
this.teamsChanged++;
transform(value: any[], filterBy: string, teamsChanged:any /*ignored*/): any[] {
<tr *ngFor="let team of teams | LeagueFilter:'points':teamsChanged; let i = index">
此附加参数将导致每次修改 teamsChanged
时调用管道。
我实现了一个 orderby 管道,它在 DOM 加载时工作正常。但是当我向列表中添加一个新项目时,我的管道没有被激活,并且已添加到列表中的新项目不是顺序的 - 但添加到列表中的最后一个位置。
管道:
import { PipeTransform, Pipe } from '@angular/core';
import { ITeam } from './team';
@Pipe({
name: "LeagueFilter"
})
export class LeagueFilterPipe implements PipeTransform {
transform(value: any[], filterBy: string): any[] {
filterBy = filterBy ? filterBy.toLocaleLowerCase() : null
for (let i = 0; i < value.length - 1; i++) {
for (let j = 0; j < value.length - 1; j++) {
if (value[j][filterBy] < value[j + 1][filterBy]) {
let temp = value[j]
value[j] = value[j + 1]
value[j + 1] = temp
}
}
}
return value;
}
}
Html:
<div class="container">
<div class="row">
<div class="col-sm-offset-1 col-sm-4">
<h2>
{{leagueTable}}
</h2>
<table class="table table-responsive">
<thead>
<tr>
<th>#</th>
<th>Team</th>
<th>Points</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams | LeagueFilter:'points'; let i = index">
<td>{{i+1}}</td>
<td>{{team.name}}</td>
<td>{{team.points}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<fieldset class="col-sm-offset-1 col-lg-3">
<legend>Add Team</legend>
<label for="name">Name </label>
<input type="text" name="" value="" [(ngModel)] = "newTeam.name" />
<br/>
<label for="name">Points</label>
<input type="text" name="" value="" [(ngModel)] = "newTeam.points" />
<button type="submit" (click)="addTeam()">Add</button>
</fieldset>
</div>
</div>
组件:
import { Component } from '@angular/core';
import { ITeam } from './team';
@Component({
selector: 'league-list',
moduleId:module.id,
templateUrl: 'league-list.component.html',
styleUrls: ['league-list.component.css']
})
export class LeagueListComponent {
leagueTable: string = "La Liga"
teams: ITeam[] = [
{ name: "Barcelona", points: 84 },
{ name: "Real Madrid", points: 85 },
{ name: "Valencia", points: 78 },
{ name: "Sevilla", points: 80 },
{ name: "Villareal", points: 62 },
]
newTeam:ITeam = { name:"", points:null };
addTeam():void{
this.teams.push(this.newTeam)
}
}
管道仅在值更改时由 Angular 执行(或管道参数,如果有的话)
您的示例中没有参数,值也没有改变。 Angulars 变化检测不检查数组的内容,仅当引用发生变化时(到不同的数组实例,对象相同。顺便说一句。)
你能做什么
- 使管道不纯净
@Pipe({
name: "LeagueFilter",
pure: false
})
这样管道将在每次更改检测时执行 运行,这可能会变得昂贵。管道应该注意不要做不必要的工作,例如缓存结果并使用 IterableDiffer
(就像在 NgFor
中使用的那样)来显式检查数组的变化。
- 修改后创建数组副本
this.teams.push(this.newTeam);
this.teams = this.teams.slice();
如果数组很大并且经常发生变化,这也会变得昂贵
- 引入一个人工管道参数
this.teams.push(this.newTeam);
this.teamsChanged++;
transform(value: any[], filterBy: string, teamsChanged:any /*ignored*/): any[] {
<tr *ngFor="let team of teams | LeagueFilter:'points':teamsChanged; let i = index">
此附加参数将导致每次修改 teamsChanged
时调用管道。