在选择模型中搜索后未选择以前的数据 angular
previous data not getting selected after search in selectionmodel angular
我正在研究 angular 选择模型,其中我有一个搜索栏,用户可以在其中搜索列表并选择项目,如果用户关闭搜索关键字,则之前选择的值,即在搜索未在选择模型中被选中之前列表。
在 ts 中搜索代码:
searchUsers(filterValue: string) {
this.previousSelectedValues = this.userSelection.selected;
console.log("came to searchUsers",filterValue);
this.searchKey = filterValue;
let params = { 'searchData': this.searchKey}
this.commCenterService.getSearchedUsers(params).subscribe((res)=>{
console.log("Search Response: Users",res);
this.users = res;
console.log("previous selected fields",this.userSelection.selected);
if(filterValue == ""){
this.previousSelectedValues.forEach(row => this.userSelection.select(row));
}
this.dataSource = new MatTableDataSource(this.users);
});
}
selectionmodel初始化代码:
userSelection = new SelectionModel<AddRecipientsList>(true, []);
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.userSelection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
masterToggle() {
this.isAllSelected() ?
this.userSelection.clear() :
this.dataSource.data.forEach(row => this.userSelection.select(row));
}
/** The label for the checkbox on the passed row */
checkboxLabel(row?: PeriodicElement): string {
if (!row) {
return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
}
}
HTML:
<div fxFlex="auto" fxLayoutAlign="start center" fxLayoutGap="10px">
<mat-form-field fxFlex="100" appearance="outline">
<input matInput type="text" (keydown.enter)="searchUsers(value)" [(ngModel)]="value">
<mat-label fxLayoutAlign="start center">
<mat-icon class="s-16">search</mat-icon>Search by Recipient Name, Email
</mat-label>
<button mat-button *ngIf="searchKey" matSuffix mat-icon-button aria-label="Clear" (click)="value=''; searchUsers(value);">
<mat-icon class="s-16">close</mat-icon>
</button>
</mat-form-field>
</div>
<div>
<mat-table [dataSource]="dataSource" class="display-table">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="userSelection.hasValue() && isAllSelected()"
[indeterminate]="userSelection.hasValue() && !isAllSelected()" [aria-label]="checkboxLabel()">
</mat-checkbox>
</mat-header-cell>>
<mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? userSelection.toggle(row) : null"
[checked]="userSelection.isSelected(row)" [aria-label]="checkboxLabel(row)">
</mat-checkbox>
</mat-cell>>
</ng-container>
<!-- recepientName Column -->
<ng-container matColumnDef="recepientName">
<mat-header-cell *matHeaderCellDef> recepient Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
</ng-container>
<!-- recepientEmail Column -->
<ng-container matColumnDef="recepientEmail">
<mat-header-cell *matHeaderCellDef> recepient Email </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.email}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
我可以从 this.userSelection.selected
中获取我之前选择的列表
我的 selection/previous 选择列表如下:
previous selected fields
0:
email: "email1@example.com"
name: "some name"
1:
email: "email2@example.com"
name: "some name"
这是如何运作的?任何的想法?谢谢。
SelectionModel 持有对对象的引用。因此,当您在 searchUsers
函数中 re-initialize this.dataSource
时,对 this.userSelection
中实际对象的引用将丢失。为了在您的用例中克服这个问题,您必须 re-initialize this.userSelection
在 new this.dataSource
中使用新对象
但是,由于您的搜索 returns 不同的列表;可能无法在新的搜索结果中找到以前的用户项目。在这种情况下,我建议使用原始值(充当用户对象的唯一 ID)来保留 SelectionModel 中的元素。这样;
selection.toggle(row.email) /** when selecting/de-selecting elements*/
和
selection.isSelected(row.email) /** when checking if an element is selected */
请注意;我建议 removig master toggle to select/unselect all elements 因为你的列表在每次搜索时都会改变,而且 selecting/unselecting all in different lists 在用户看来有点模棱两可。
我也在这里创建了一个演示;
https://stackblitz.com/edit/angular-e9brcp
在您的 html 中,更新此部分
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? userSelection.toggle(row) : null"
[checked]="userSelection.isSelected(row)" [aria-label]="checkboxLabel(row)">
</mat-checkbox>
至此
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? userSelection.toggle(row.email) : null"
[checked]="userSelection.isSelected(row.email)">
</mat-checkbox>
我正在研究 angular 选择模型,其中我有一个搜索栏,用户可以在其中搜索列表并选择项目,如果用户关闭搜索关键字,则之前选择的值,即在搜索未在选择模型中被选中之前列表。
在 ts 中搜索代码:
searchUsers(filterValue: string) {
this.previousSelectedValues = this.userSelection.selected;
console.log("came to searchUsers",filterValue);
this.searchKey = filterValue;
let params = { 'searchData': this.searchKey}
this.commCenterService.getSearchedUsers(params).subscribe((res)=>{
console.log("Search Response: Users",res);
this.users = res;
console.log("previous selected fields",this.userSelection.selected);
if(filterValue == ""){
this.previousSelectedValues.forEach(row => this.userSelection.select(row));
}
this.dataSource = new MatTableDataSource(this.users);
});
}
selectionmodel初始化代码:
userSelection = new SelectionModel<AddRecipientsList>(true, []);
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.userSelection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
masterToggle() {
this.isAllSelected() ?
this.userSelection.clear() :
this.dataSource.data.forEach(row => this.userSelection.select(row));
}
/** The label for the checkbox on the passed row */
checkboxLabel(row?: PeriodicElement): string {
if (!row) {
return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
}
}
HTML:
<div fxFlex="auto" fxLayoutAlign="start center" fxLayoutGap="10px">
<mat-form-field fxFlex="100" appearance="outline">
<input matInput type="text" (keydown.enter)="searchUsers(value)" [(ngModel)]="value">
<mat-label fxLayoutAlign="start center">
<mat-icon class="s-16">search</mat-icon>Search by Recipient Name, Email
</mat-label>
<button mat-button *ngIf="searchKey" matSuffix mat-icon-button aria-label="Clear" (click)="value=''; searchUsers(value);">
<mat-icon class="s-16">close</mat-icon>
</button>
</mat-form-field>
</div>
<div>
<mat-table [dataSource]="dataSource" class="display-table">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="userSelection.hasValue() && isAllSelected()"
[indeterminate]="userSelection.hasValue() && !isAllSelected()" [aria-label]="checkboxLabel()">
</mat-checkbox>
</mat-header-cell>>
<mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? userSelection.toggle(row) : null"
[checked]="userSelection.isSelected(row)" [aria-label]="checkboxLabel(row)">
</mat-checkbox>
</mat-cell>>
</ng-container>
<!-- recepientName Column -->
<ng-container matColumnDef="recepientName">
<mat-header-cell *matHeaderCellDef> recepient Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
</ng-container>
<!-- recepientEmail Column -->
<ng-container matColumnDef="recepientEmail">
<mat-header-cell *matHeaderCellDef> recepient Email </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.email}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
我可以从 this.userSelection.selected
我的 selection/previous 选择列表如下:
previous selected fields
0:
email: "email1@example.com"
name: "some name"
1:
email: "email2@example.com"
name: "some name"
这是如何运作的?任何的想法?谢谢。
SelectionModel 持有对对象的引用。因此,当您在 searchUsers
函数中 re-initialize this.dataSource
时,对 this.userSelection
中实际对象的引用将丢失。为了在您的用例中克服这个问题,您必须 re-initialize this.userSelection
在 new this.dataSource
但是,由于您的搜索 returns 不同的列表;可能无法在新的搜索结果中找到以前的用户项目。在这种情况下,我建议使用原始值(充当用户对象的唯一 ID)来保留 SelectionModel 中的元素。这样;
selection.toggle(row.email) /** when selecting/de-selecting elements*/
和
selection.isSelected(row.email) /** when checking if an element is selected */
请注意;我建议 removig master toggle to select/unselect all elements 因为你的列表在每次搜索时都会改变,而且 selecting/unselecting all in different lists 在用户看来有点模棱两可。
我也在这里创建了一个演示;
https://stackblitz.com/edit/angular-e9brcp
在您的 html 中,更新此部分
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? userSelection.toggle(row) : null"
[checked]="userSelection.isSelected(row)" [aria-label]="checkboxLabel(row)">
</mat-checkbox>
至此
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? userSelection.toggle(row.email) : null"
[checked]="userSelection.isSelected(row.email)">
</mat-checkbox>