簡體   English   中英

Ng-Select - 使用 ControlValueAccessor 接口選擇/取消選擇自定義組件中的所有項目

[英]Ng-Select - Select/Unselect all items in custom component using the ControlValueAccessor interface

我正在嘗試使用 ng-select 和controlValueAccessor接口包裝設置多選(使用每個選項的復選框)組合所需的所有配置。

到目前為止它有點工作,除了如果我選擇通過放置在列表頂部的復選框選擇或取消選擇所有項目,只會更新表單中的值,而不是控件中的選擇。 在此處輸入圖片說明

該控件僅在我單獨選擇或取消選擇項目時按預期工作,然后控件和表單值都會相應地更新:

在此處輸入圖片說明

這是可重用組件的代碼:

打字稿

import { Component, Input, OnInit, Self, ViewChild } from '@angular/core';
import { ControlValueAccessor, NgControl } from '@angular/forms';

@Component({
  selector: 'app-multi-select',
  templateUrl: './multi-select.component.html',
  styleUrls: ['./multi-select.component.css']
})
export class MultiSelectComponent implements OnInit, ControlValueAccessor {

  disabled: boolean;
  selectedValues: any;

  @Input() optionItems: any[];
  @ViewChild('combo', { static: true }) combo;
  constructor(@Self() public controlDir: NgControl) {
    this.controlDir.valueAccessor = this;
  }

  ngOnInit(): void {
  }

  toggleCheckAll(values: any) {
    if (values.currentTarget.checked) {
      this.selectAllItems();
    } else {
      this.unselectAllItems();
    }
  }
  onChange(event) {
    debugger;
  }

  onTouched() {}

  onSelectionChange(selectedItems) {
    debugger;
    if (Array.isArray(selectedItems)) {
      const newList = selectedItems.map((x) => x.id);
      this.selectedValues = [...newList]
      this.onChange([...newList]);
    }
    this.onTouched();
  }

  writeValue(obj: any): void {
    this.combo.select([...obj]);
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  private selectAllItems() {
    const newList = this.optionItems.map((x) => x.id);
    this.selectedValues = [...newList];
    this.onChange([...newList]);
  }

  private unselectAllItems() {
    this.selectedValues = [];
    this.onChange([]);
  }

}

HTML

<ng-select 
  #combo
  [multiple]="true" 
  [items]="optionItems"
  [closeOnSelect]="false"
  (change)="onSelectionChange($event)"   
  (blur)="onTouched()"    
  placeholder="Select people"
    bindLabel="name"
  bindValue="id">

    <ng-template ng-header-tmp let-items="items">
        <input type="checkbox"  (change)="toggleCheckAll($event)"/>
        </ng-template>

        <ng-template ng-multi-label-tmp let-items="items" let-clear="clear">
            <div class="ng-value" *ngFor="let item of items | slice:0:2">
                <span class="ng-value-label">{{item.name}}{{item.login}}</span>
                <span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
            </div>
            <div class="ng-value" *ngIf="items.length > 2">
                <span class="ng-value-label">{{items.length - 2}} more...</span>
            </div>
        </ng-template>

        <ng-template ng-option-tmp let-item="item" let-item$="item$" let-index="index">
            <input id="item-{{index}}" type="checkbox" [checked]="item$.selected" /> {{item.name}}
    </ng-template>
</ng-select>

你可以在 stackblitz 上的這個演示中找到完整的代碼

順便說一句:我不得不在onSelectionChange放置一個條件來檢查傳入的參數是否是一個數組,因為令我驚訝的是,即使我使用放置在列表頂部的復選框,也會調用change事件,而不僅僅是在我選擇或取消選擇單個選項。

您可以使用 ngModel 指令將選定的值綁定到 ng-select。

嘗試這個:

<ng-select #combo [multiple]="true" [items]="optionItems" [closeOnSelect]="false" (change)="onSelectionChange($event)"
    (blur)="onTouched()" placeholder="Select people" bindLabel="name" [ngModel]="selectedValues" bindValue="id">

    <ng-template ng-header-tmp let-items="items">
        <input type="checkbox" [ngModel]="checkAll"  (change)="toggleCheckAll($event)"/>
        </ng-template>

        <ng-template ng-multi-label-tmp let-items="items" let-clear="clear">
            <div class="ng-value" *ngFor="let item of items | slice:0:2">
                <span class="ng-value-label">{{item.name}}{{item.login}}</span>
                <span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
            </div>
            <div class="ng-value" *ngIf="items.length > 2">
                <span class="ng-value-label">{{items.length - 2}} more...</span>
            </div>
        </ng-template>

        <ng-template ng-option-tmp let-item="item" let-item$="item$" let-index="index">
            <input id="item-{{index}}" type="checkbox" [checked]="item$.selected" /> {{item.name}}
    </ng-template>
</ng-select>

然后在您的課程中將值設置為 selectedValue ,如下所示:

組件.ts

 writeValue(obj: any): void {
    this.selectedValues =[...obj];
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM