将新项添加到列表时,角度为2,自定义管道不重新排序列表

时间:2016-11-24 06:37:07

标签: html angular pipe angularjs-orderby

我实现了一个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&nbsp;&nbsp;</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)

    }
}

1 个答案:

答案 0 :(得分:3)

如果值发生变化,管道仅由Angular执行(如果有管道,则由管道参数执行)

您的示例中没有参数,值不会更改。 Angulars更改检测不会检查数组的内容,只有当引用更改时(对于不同的数组实例,对于对象btw相同。)

你能做什么

  • 使管道非纯净
@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时调用管道。