2016-09-28 13 views
1

このページには、ダイブの一覧が表示されます。「ダイブの追加」、「ダイブのクリア」、および検索ボックスが表示されます。アンギュラング角2冊、第1章例5

これはテンプレートである:

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

フィルタが呼び出され、リスト取得されます検索ボックスに入力するたびに再レンダリングされますが、[追加]ボタンをクリックしたときは表示されません。検索ボックスに何かがある場合、検索ボックスの内容によって新しいアイテムが表示されても、「追加」ボタンはダイビングリストの変更にはなりません。 「追加」ボタンをクリックすると表示されたダイビングリストが再レンダリングされるようにコードを変更するにはどうすればよいですか?

答えて

3

あなたは純粋なパイプにそれが入力値に純粋 変更を検出した場合にのみ実行されますtransformので

その方法を持っています。

あなたのケース

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

の入力値divessearchBox.value

According to the angular2 guide on pipes:

純粋な変更プリミティブ入力への変更のいずれかであるだろう値 (String、Number、Boolean、Symbol)または変更されたオブジェクト参照(Date、 Array、Function、Object)。

  • diveを添加する場合、配列参照(ダイブ)が変更されていない - 従ってtransform方法は実行されません。
  • フィルタ入力に何かが入力されると、searchBox.valueが変更されます。したがって、transformが実行されます。ただ、置き換え

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

    で:

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

    または

だからpossiblesソリューションの1つは、新しい参照配列に必ずdiv要素が追加されるたびに持っていることです:

this.dives = [...this.dives, this._stockDives[this._index++]]; 
作業それを行うには210

第二の方法は、impure pipeを使用している:

@Pipe({name: 'contentFilter', pure: false }) 
関連する問題