我有一个Angular 2组件,它在 *ngFor
中加载并显示用户的复选框列表,也可以根据键过滤列表 . 我需要选择所有过滤的项目并将它们添加到数组中 . 我可以检查所有复选框,但问题是当我更改 checked
有问题 change
事件没有触发时,任何想法如何解决这个问题?
模板:
<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 = [];
}
}
3 回答
更新
更新了示例代码和plunker以演示选择/取消选中已筛选列表的所有复选框 .
根据我的理解,过滤器行为从Angular1变为Angular2 .
在Angular1中,当修改数据或过滤器参数时,将重新计算DOM(网页) . (我可能在很久以前就错了:P)
在Angular2中,简而言之,修改数据(数组)不会触发过滤器计算,因此没有新结果,也没有更新到DOM .
长官方解释如下:Angular2 Pipes - ts . 如果您坚持在模板中使用管道(过滤器),则应浏览文档中的 impure pipe 部分 .
另一种解决方案是不使用带有
*ngFor
的过滤器 . 改为创建筛选列表 .Plunker
http://plnkr.co/edit/pEpaj0?p=preview
示例代码
app.component.ts
app.component.html
当您尝试选择所有设备时,主列表未更新,没有任何更改,角度也没有检测到它的更改 . (有一个更新的标志,但列表是相同的) . 您有两种选择:
在列表中的每个已检查元素上放置一个标志 .
使用ApplicationRef.tick()触发手动渲染https://angular.io/docs/ts/latest/api/core/index/ApplicationRef-class.html#!#tick-anchor
注意:您的代码可能会有所不同,因为我做了一些更改才能获得正常工作的应用 . 请从代码片段中获取相关部分并申请 .
这是您的问题的工作代码 .
以下是您需要对代码进行的更改 .
更改您的全部选择功能,如下所示 .
注意:
this.strFilter
是组件类/功能中的过滤器功能 . 这取决于您的Filter类 . 我已经像这样创建了过滤器/管道 .//stringfilter.pipe.ts
在组件类中,我确实喜欢//组件类
和
我测试了以下代码 . 希望这能解决你的问题 .