繰り返したい文字列のリストがありますが、検索語を使用してそれらをフィルタリングできるようにします。このような:
<div *ngFor="#item in list | search: searchTerm">{{ item }}</div>
私の質問は:パイプがリストの空のサブセットを返すかどうかを確認するにはどうすればよいですか?
つまり、検索語に一致する文字列がない場合、「一致しない」というメッセージを表示したいのです。
<div *ngIf="(list | search: searchTerm).length === 0">
"No matches"
</div>
<div *ngFor="#item in list | search: searchTerm">{{ item }}</div>
または、リストが空であることを示す特定のトークンを返すようにパイプを変更することもできます
@Pipe({
name: 'search'
})
export class SearchPipe {
transform(value, searchTerm) {
let result = ...
if(result.length === 0) {
return [-1];
}
return result;
}
}
<ng-container *ngFor="let item of list | search: searchTerm">
<div *ngIf="item === -1">"No matches"</div>
<div *ngIf="item !== -1">{{ item }}</div>
</ng-container>
これを実現するもう1つの方法は、子要素または私の場合はテーブルの行のhtml要素をチェックすることです。
<table #myTable>
<tr *ngFor="let item of list | somePipe : searchText">
<td>{{ item.name }}</td>
</tr>
</table>
<p *ngIf="!myTable.rows.length">No results</p>
これは@GünterZöchbauerから少し変更した私のコードです
<div *ngFor="let filter_list of list | FilterItem" >
<div *ngIf=" filter_list == -1 " class="alert alert-info">No item found</div>
<div *ngIf="filter_list !== -1" *ngFor="let item of filter_list ; let i = index;" >
{{ item }}
</div>
</div>
パイプコード
@Pipe({
name: 'FilterItem'
})
export class FilterItem {
transform(list, args?) {
let result = ...;
if ( result && result.length > 0 ){
return [ result ];
}else{
return [ -1 ];
}
}
}
パイプへの依存性注入を活用できます。コンポーネントを注入できます:
次に、そのことを通知するプロパティを設定できます。
@Pipe({
name: 'search'
})
export class SearchPipe {
constructor(@Inject(forwardRef(() => SomeComponent)) private comp:SomeComponent) {
}
transform(value) {
var filtered = value.map((v) => v-1);
this.comp.isEmpty = (filtered.length === 0);
return filtered;
}
}
主な欠点は、コンポーネント内でパイプをリンクすることです。利点は、フィルタリングが1回実行されることです。
あなたの目的が、CSSクエリでできるよりも要素をレンダリングするだけなら、私は GünterZöchbauer コードを休ませます。
<ng-container *ngFor="let item of list | search: searchTerm">
<div *ngIf="item !== -1">{{ item }}</div>
<div class="empty">"No matches"</div>
</ng-container>
CSS
div.empty {
display:none;
}
div.empty:first-child {
display:block;
}
.list div.empty {
display: none;
}
.list div.empty:first-child {
display: block;
}
<h4>If you hava record to display than</h4>
<div class="list">
<div>The first record.</div>
<div>The second record.</div>
<div>The third record.</div>
<div class="empty">"No matches"</div>
</div>
<br>
<h4>If no record to show</h4>
<div class="list">
<div class="empty">"No matches"</div>
</div>
これは、私が作成した中で最もクリーンなソリューションです。
@Pipe({
name: 'search'
})
export class SearchPipe {
transform(value, searchTerm) {
let result = ...
if(result.length === 0) {
return [undefined];
}
return result;
}
}
[undefined]
を返すことにより、DOMでのチェックはずっときれいで読みやすくなります。
<ng-container *ngFor="let item of list | search: searchTerm">
<div *ngIf="!item">"No matches"</div>
<div *ngIf="item">{{ item }}</div>
</ng-container>
angular変数でngIfをサポートするようになりました。パイプの結果を新しい変数に割り当てて、ifブロック内でループを実行できます。
<ng-container *ngIf="search: searchTerm as results; else noItems">
<!-- else is for cases where search:Search term is undefined or null -->
<div *ngFor="let item of results">{{item}}</div>
<!-- the case where the pipe returns an empty array -->
<div *ngIf="!result.length">no items match the search</div>
</ng-container>
<ng-template #noItems>searching...</ng-template>