предыдущие данные не выбираются после поиска в модели выбора угловых - PullRequest
0 голосов
/ 10 июня 2019

Я работаю над угловой моделью выбора, где у меня есть панель поиска, где пользователь ищет список и выбирает элементы, а если пользователь закрывает ключевое слово для поиска, то ранее выбранные значения, т. Е. До того, как поиск не будет выбран в списке моделей выбора.

Поиск кода в тс :

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

Мой выбор / предыдущий выбранный список ниже:

previous selected fields 
0:
 email: "email1@example.com"
 name: "some name" 
1:
 email: "email2@example.com"
 name: "some name"

Как это работает?Любая идея?Спасибо.

1 Ответ

0 голосов
/ 10 июня 2019

SelectionModel содержит ссылки на объекты.Поэтому при повторной инициализации функции this.dataSource в searchUsers ссылки на реальные объекты в this.userSelection теряются.Чтобы преодолеть это в вашем случае использования, вы должны повторно инициализировать this.userSelection с новыми объектами в новых this.dataSource

Однако, так как ваш поиск возвращает разные списки;может оказаться невозможным найти элементы предыдущего пользователя в новых результатах поиска.В этом случае я предлагаю использовать примитивное значение (которое действует как уникальный идентификатор для пользовательских объектов) для хранения элементов в SelectionModel.Так, что;

selection.toggle(row.email) /** when selecting/de-selecting elements*/

и

selection.isSelected(row.email) /** when checking if an element is selected */

Обратите внимание, что;я предлагаю переключить мастер удаления, чтобы выбрать / отменить выбор всех элементов, потому что ваш список меняется при каждом поиске, а выбор / отмена выбора всех в разных списках кажется немного неоднозначным с точки зрения пользователя.

Я также создал демо здесь;

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>
...