我有一个Angular 2组件,它加载并显示* ngFor中的用户的复选框列表,该列表也可以根据键过滤.我需要选择所有过滤的项目并将它们添加到数组中.我可以检查所有的复选框,但问题是当我更改检查有问题的更改事件不触发,任何想法如何解决这个问题?
模板:
- <div class="form-group">
- <input type="text" class="form-control" id="stringKeyFilter" placeholder="Key Filter"
- [(ngModel)]="keyFilter">
- </div>
- <table class="table table-striped table-hover">
- <thead>
- <tr>
- <th>Id</th>
- <th style="width: 150px;">Action</th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let device of devices| stringFilter: keyFilter">
- <td>
- {{device.$key}}
- </td>
- <td>
- <div class="checkBox">
- <label> <input type="checkBox"
- [checked]="selectAll || selectedDevices.indexOf(device.$key) > -1"
- (change)="updateSelectedDevices(device.$key,$event)" > View</label>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- <div class="btn-group pull-right">
- <button type="button" class="btn btn-primary" (click)="selectAllDevices()">Select All</button>
- <button type="button" class="btn btn-default" (click)="deselectAllDevices()">Deselect All
- </button>
- </div>
零件:
- @Component({
- moduleId: module.id,selector: 'device-list',template: template
- })
- export class DeviceListComponent implements OnInit {
- devicesObservable: FirebaseListObservable<Device[]>;
- devices: Device[] = [];
- isLoading: boolean = true;
- selectedDevices: string[] = [];
- selectAll: boolean = false;
- allCtrl: any;
- keyFilter: string = '';
- constructor(private af: AngularFire) {
- }
- ngOnInit(): void {
- this.devicesObservable = this.af.database.list('/online',{
- query: {
- orderByKey: true,}
- });
- this.devicesObservable.subscribe((devicesData)=> {
- this.devices = devicesData;
- this.isLoading = false
- });
- }
- updateSelectedDevices(deviceId: string,event): void {
- if (event.target.checked) {
- this.selectedDevices.push(deviceId);
- }
- else {
- _.pull(this.selectedDevices,deviceId);
- }
- }
- loadingDeviceDetail(loading: boolean): void {
- this.isLoading = loading;
- }
- selectAllDevices(): void {
- this.selectAll = true;
- }
- deselectAllDevices(): void {
- this.selectAll = false;
- this.selectedDevices = [];
- }
- }
更新
更新示例代码和空格以演示选择/取消选中所有过滤列表的复选框.
根据我的理解,过滤器行为从Angular1改变为Angular2.
在Angular1中,当数据或过滤器参数被修改时,DOM(网页)将被重新计算. (我也许错了,太久以前:P)
在Angular2中,简而言之,修改数据(数组)不会触发过滤器的计算,所以没有新的结果,不会更新到DOM.
长期和正式的解释在这里:Angular2 Pipes – ts.如果您坚持在模板中使用管道(过滤器),您应该探索文档中不纯的管道部分.
另一个解决方案是不要使用带* ngFor的过滤器.创建过滤的列表.
Plunker
http://plnkr.co/edit/pEpaj0?p=preview
示例代码
app.component.ts
- import {Component} from '@angular/core';
- import {bootstrap} from '@angular/platform-browser-dynamic';
- @Component({
- selector: 'material-app',templateUrl: 'app.component.html'
- })
- export class AppComponent {
- title='How to select all filtered checkBoxes inside ngFor in Angular 2?';
- url='https://stackoverflow.com/questions/39703103/';
- device = [
- {'name':'abc','checked':false},{'name':'abcd',{'name':'abcde',{'name':'abc123',{'name':'abc1234','checked':false}];
- deviceFilter = '';
- deviceFiltered = this.device.slice(0);
- selectFiltered(){
- this.deviceFiltered.forEach(i=>i.checked=true);
- }
- deSelectFiltered(){
- this.deviceFiltered.forEach(i=>i.checked=false);
- }
- onFilterChange(){
- if (this.deviceFilter.length > 0) {
- this.deviceFiltered = this.device.filter(i => i.name.indexOf(this.deviceFilter) > -1);
- console.log(this.deviceFiltered);
- } else {
- this.deviceFiltered = this.device.slice(0);
- }
- }
- }
app.component.html
- <h2><a [href]="titleUrl">{{title}}</a></h2>
- <div>
- Filter
- <input [(ngModel)]="deviceFilter" (ngModelChange)="onFilterChange()">
- </div>
- <div>
- List:
- <ul>
- <li *ngFor="let i of device">
- <input type="checkBox" [(ngModel)]="i.checked">{{i.name}}
- </li>
- </ul>
- </div>
- <div>
- Filtered List:
- <ul>
- <li *ngFor="let i of deviceFiltered">
- <input type="checkBox" [(ngModel)]="i.checked">{{i.name}}
- </li>
- </ul>
- <button (click)="selectFiltered()">Select Filtered</button>
- <button (click)="deSelectFiltered()">Deselect Filtered</button>
- </div>