【问题标题】:Unraveling Angular 2 book, Chapter 1, Example 5Unraveling Angular 2 book, Chapter 1, Example 5
【发布时间】:2016-09-28 21:02:17
【问题描述】:

该页面显示了一个潜水列表,它有一个“添加新潜水”、“清除潜水”和一个搜索框,它会在您输入时过滤显示的列表。

这是模板:

<div class="container-fluid">

  <h1>My Latest Dives (Angular/TypeScript)</h1>
  <div class="row">
    <div class="col-sm-5">
      <button class="btn btn-primary btn-lg"
        [disabled]="!enableAdd()"
        (click)="addDive()">
          Add new dive
      </button>
      <button class="btn btn-danger btn-lg"
        (click)="clearDives()">
          Clear dives
      </button>
    </div>
    <div class="col-sm-4 col-sm-offset-3">
      <input #searchBox class="form-control input-lg"
        placeholder="Search"
        (keyup)="0" />
    </div>
  </div>
  <div class="row">
    <div class="col-sm-4"
      *ngFor="let dive of dives | contentFilter:searchBox.value">
      <h3>{{dive.site}}</h3>
      <h4>{{dive.location}}</h4>
      <h2>{{dive.depth}} feet | {{dive.time}} min</h2>
    </div>
  </div>
</div>

这是组件代码:

import {Component} from '@angular/core';

@Component({
  selector: 'divelog',
  templateUrl: 'app/dive-log.template.html'
})

export class DiveLogComponent {
  public dives = [];
  private _index = 0;
  private _stockDives = [
  {
    site: 'Abu Gotta Ramada',
    location: 'Hurghada, Egypt',
    depth: 72,
    time: 54
  },
  {
    site: 'Ponte Mahoon',
    location: 'Maehbourg, Mauritius',
    depth: 54,
    time: 38
  },
  {
    site: 'Molnar Cave',
    location: 'Budapest, Hungary',
    depth: 98,
    time: 62
  }];

  public enableAdd() {
    return this._index < this._stockDives.length;
  }

  public addDive() {
    if (this.enableAdd()) {
      this.dives.push(this._stockDives[this._index++]);
    }
  }

  public clearDives() {
    this.dives = [];
    this._index = 0;
  } 
}

这是过滤代码:

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({name: 'contentFilter'})
export class ContentFilterPipe implements PipeTransform {

  transform(value: any[], searchFor: string) : any[] {
    if (!searchFor) return value;

    searchFor = searchFor.toLowerCase();
    return value.filter(dive => 
      dive.site.toLowerCase().indexOf(searchFor) >= 0 ||
      dive.location.toLowerCase().indexOf(searchFor) >= 0 ||
      dive.depth.toString().indexOf(searchFor) >= 0 ||
      dive.time.toString().indexOf(searchFor) >= 0);
  }
}

每当我在搜索框中输入内容时,都会调用过滤器并重新呈现列表,但当我单击“添加”按钮时不会。如果我在搜索框中有内容,“添加”按钮不会导致潜水列表的更改,即使搜索框的内容允许显示新项目。如何更改代码,以便单击“添加”按钮会导致显示的潜水列表重新呈现?

【问题讨论】:

    标签: javascript angular typescript


    【解决方案1】:

    你有一个纯管道所以

    它的方法transform只会在它检测到一个纯 更改为输入值。

    根据你的情况

    *ngFor="let dive of dives | contentFilter:searchBox.value"
    

    输入值将为divessearchBox.value

    According to the angular2 guide on pipes:

    纯粹的改变是对原始输入值的改变 (字符串、数字、布尔值、符号)或更改的对象引用(日期、 数组、函数、对象)。

    • 添加dive 时,数组引用(dives)不会改变——因此transform 方法不会被执行。
    • 当在过滤器输入中输入内容时,searchBox.value 会发生变化 - 因此会执行 transform

    因此,一种可能的解决方案是每次添加 div 时始终拥有一个新的引用数组:

    只需替换:

    this.dives.push(this._stockDives[this._index++]);
    

    与:

    this.dives = this.dives.concat(this._stockDives[this._index++]);
    

    或:

    this.dives = [...this.dives, this._stockDives[this._index++]];
    

    第二种方法是使用 impure pipe:

    @Pipe({name: 'contentFilter', pure: false })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 2019-01-10
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多