解开Angular 2书,第1章,例5 [英] Unraveling Angular 2 book, Chapter 1, Example 5

查看:107
本文介绍了解开Angular 2书,第1章,例5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The page shows a list of dives, it has an "add new dive", "clear dives" and a search box, which filters the displayed list as you type into it.

这是模板:

<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);
  }
}

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

The filter is getting invoked and the list is getting rerendered whenever I type into the search box, but not when I click "add" button. If I have something in the search box, "add" button does not result in the change of the dive list even though the content of the search box allows the new items to be displayed. How do I change the code so that clicking the "add" button would cause rerendering of the displayed list of dives?

推荐答案

您有一个纯管道所以


它的方法转换只有当它检测到输入值的纯
更改时才会执行。

its method transform will be executed only when it detects a pure change to the input value.

对于你的情况

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

输入值潜水 searchBox.value

根据有关管道的angular2指南:


纯更改是对原始输入值的更改
(String,Number,Boolean ,Symbol)或更改的对象引用(Date,
Array,Function,Object)。

A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).




  • 当添加潜水时,数组引用(潜水)不会更改 - 因此转换方法不是执行。

  • 当在过滤器输入中输入内容时, searchBox.value 确实发生了变化 - 因此 transform 已执行。

    • When a dive is added, the array reference (dives) isn't changed – hence transform method is not executed.
    • When something is typed into the filter input, searchBox.value does change - hence transform is executed.
    • 所以可能的解决方案之一是每次添加div时总是有一个新的参考数组:

      So one of possibles solutions is to have always a new reference array each time a div is added:

      只需替换:

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

      with:

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

      或:

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

      第二种方法是使用 不纯的烟斗

      Second way to do it working is use impure pipe:

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

      这篇关于解开Angular 2书,第1章,例5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆