Рассчитать только выбранные значения Angular Список выбора материала - PullRequest
4 голосов
/ 28 марта 2020

У меня есть простой Angular Список выбора материала с некоторыми значениями внутри него.

Мое требование - рассчитать сумму только выбранных (отмеченных) значений (и после этого применить скидку к цена, если она превышает некоторую сумму).

Я считаю, что это должно быть легко, но я новичок в Angular и Материальных компонентах, и почему-то не могу найти то, что я хочу, в Google или здесь ... Мой код как показано ниже:

HTML

 <mat-selection-list #options>
    <mat-list-option *ngFor="let option of optionArray">
      {{option.name}} - ${{option.price}}

    </mat-list-option>
  </mat-selection-list>

  <p>
    You have selected {{options.selectedOptions.selected.length}} items with total sum of $ {{  }}. </p>
  <p *ngIf="">
    Your discount is 10%. </p>

TS

interface Options {
  name: string;
  price: number;
}

optionArray: Options[] = [
    {
      name: 'Item 1',
      price: 4000
    },
    {
      name: 'Item 2',
      price: 8000
    },
    {
      name: 'Item 3',
      price: 3500
    },
    {
      name: 'Item 4',
      price: 500
    }
  ]

Заранее спасибо!

Ответы [ 3 ]

5 голосов
/ 28 марта 2020

Присоедините модель и событие изменения к вашему элементу списка выбора матов, а затем вы можете использовать методы javascript: map, Reduce.

HTML:

<mat-selection-list #options [(ngModel)]="selectedOptions" (ngModelChange)="onSelectedOptionsChange($event)">
    <mat-list-option *ngFor="let option of optionArray">
        {{option.name}} - ${{option.price}}
    </mat-list-option>
</mat-selection-list>

<p>
    You have selected {{selectedOptions.selected.length}} items with total sum of $ {{ totalSum }}. </p>
<p *ngIf="..."> Your discount is 10%. </p>

Контроллер TS:

onSelectedOptionsChange() {
    this.totalSum = this.selectedOptions
        .map((option: Options) => option.price)
        .reduce((priceA: number, priceB: number) => priceA + priceB)
}

Надеюсь, это поможет.

3 голосов
/ 28 марта 2020

Вы можете просто go реагировать. Возьмите экземпляр MatSelectionList с помощью ViewChild:

@ViewChild(MatSelectionList, { static: true }) matSelectionOptionsComponentRef: MatSelectionList;

... и выполните вычисления / назначьте наблюдаемые, прослушивая EventEmitter из ит.


TS :

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'app-selector',
  styleUrls: ['./app-selector.css'],
  templateUrl: './app-selector.html'
})
export class AppSelectorComponent {
  @ViewChild(MatSelectionList, { static: true })
  readonly matSelectionOptionsComponentRef: MatSelectionList;
  readonly options: readonly Options[] = [
    { name: 'Item 1', price: 4000 },
    { name: 'Item 2', price: 8000 },
    { name: 'Item 3', price: 3500 },
    { name: 'Item 4', price: 50 }
  ];
  hasDiscount$: Observable<boolean>;
  sum$: Observable<number>;

  ngOnInit(): void {
    this.sum$ = this.matSelectionOptionsComponentRef.selectionChange.pipe(
      map(({ source }) => {
        return source.selectedOptions.selected
          .map(({ value }) => value)
          .reduce((previousValue, currentValue) => {
            return previousValue + currentValue;
          }, 0);
      }),
      startWith(0)
    );
    this.hasDiscount$ = this.sum$.pipe(
      map(value => value > 10000), // PUT THE CORRECT VALUE HERE
      startWith(false)
    );
  }
}

HTML:

<mat-selection-list>
  <mat-list-option class="selected" *ngFor="let option of options" [value]="option.price">
    {{ option.name }} - ${{ option.price }}
  </mat-list-option>
</mat-selection-list>

<p>You have selected {{ matSelectionOptionsComponentRef.selectedOptions.selected.length }} 
  items with total sum of ${{ sum$ | async }}.</p>
<p *ngIf="hasDiscount$ | async">Your discount is 10%.</p>

DEMO

3 голосов
/ 28 марта 2020

Есть несколько способов достичь этого. Вот еще один способ без привязки к свойству модели и только с использованием переменной шаблона.

Шаблон

<mat-selection-list #options (selectionChange)="onSelectionChange()">
  <mat-list-option *ngFor="let option of optionsArray" [value]="option">
    {{option.name}} - ${{option.price}}
  </mat-list-option>
</mat-selection-list>

<p>You have selected {{options.selectedOptions.selected.length}} items with total sum of ${{ sum }}.</p>
<p *ngIf="discount">Your discount is 10%. </p>

Контроллер

export class ListSelectionExample {
  @ViewChild('options') optionsSelectionList: MatSelectionList;
  optionsArray: Options[] = [
    { name: 'Item 1', price: 4000 },
    { name: 'Item 2', price: 8000 },
    { name: 'Item 3', price: 3500 },
    { name: 'Item 4', price: 50 }
  ];
  sum = 0;
  discount = false;

  onSelectionChange() {
    this.getSum();
  }

  getSum() {
    this.sum = 0;
    this.discount = false;

    this.optionsSelectionList.selectedOptions.selected
      .map(s => s.value)
      .forEach(option => this.sum += option.price);

    if (this.sum > 12500) {   // apply discount if sum > $12500
      this.sum = this.sum * 0.9;
      this.discount = true;
    }
  }
}

Рабочий пример: Stackblitz

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...