html - Angular 2将新项目添加到列表时,自定义管道不重新排序列表

标签 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)

    }
}

最佳答案

只有当值发生变化(或者管道的参数,如果有的话)发生变化时,管道才会由 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 时调用管道。

关于html - Angular 2将新项目添加到列表时,自定义管道不重新排序列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40779520/

相关文章:

javascript - Angular FormControl 模式验证器不适用于正则表达式

html - 如果来自 HTML 绑定(bind)的对象的 *ngFor Let 对象返回空数组,如何显示占位符

Angular 4 - 处理迭代中嵌套订阅的最佳方法是什么

python - 什么可以使 connection.send() 阻塞? (来自 conn1、conn2 = multiprocessing.Pipe() )

linux - Bash 匿名管道

javascript - 使用一个 html 页面的下拉列表到另一个 html 页面

python - 存储模型的django表单下拉列表

forms - 在 Angular 中同时实时显示 Reactive 表单元素

angular - 如何关闭 Angular v8 中的差异加载?

bash - 根据输入在命令中的 "|"和 "&&"符号之间切换