简体   繁体   English

Angular 材料 - 多个 Select - 最后选择的值

[英]Angular Material - Multiple Select - Last selected value

When working with mat-select, you can subscribe to an event "selectionChange".使用 mat-select 时,您可以订阅事件“selectionChange”。

<mat-select
    [(ngModel)]="value"
    name="someName"
    multiple="true"
    (selectionChange)="handleEvent($event)"
>
    <mat-option
        *ngFor="let val of values"
        [value]="val"
    >
        {{ val }}
    </mat-option>
</mat-select>
handleEvent(event: MatSelectChange) {
    console.log(event.value); // => array of values
}

This will emit a MatSelectChange where you access the current value of the select.这将发出一个 MatSelectChange,您可以在其中访问 select 的当前值。

The problem is, when working with multiple selection, the value property will contains an array with all the currently selected values.问题是,当使用多项选择时, value 属性将包含一个包含所有当前选定值的数组。

What I need, is to know what was the last value the user selected.我需要的是知道用户选择的最后一个值是什么。 I have print out the MatSelectChange event to see if there is anything I could use (like, previous values, so I can compare), but, sadly, I don't see anything.我已经打印出 MatSelectChange 事件以查看是否有任何我可以使用的东西(例如,以前的值,所以我可以比较),但遗憾的是,我什么也没看到。

Is it possible to achieve that?有可能实现吗?

If you use a FormControl instead of ngModel you can subscribe to the valueChanges Observable to get the previous and next values.如果您使用 FormControl 而不是ngModel ,您可以订阅valueChanges Observable以获取上一个和下一个值。 There is a post here that covers this topic: Form control valueChanges gives the previous value这里有一篇文章涵盖了这个主题: 表单控件 valueChanges 给出了以前的值

Basically what you need to do is to declare a new FormControl in your ts-file;基本上你需要做的是在你的 ts 文件中声明一个新的 FormControl;

formControl = new FormControl();

..and bind to it like this; ..并像这样绑定它;

<mat-select
    [formControl]="formControl"
    name="someName"
    multiple>

...and check for changes like this; ...并检查这样的变化;

formControl
  .valueChanges
  .pipe(pairwise())
  .subscribe(([prev, next]: [any, any]) => ... );

Since I cannot use ReactiveForm and have to stick with Template Driven, I came up with this solution:由于我不能使用 ReactiveForm 并且必须坚持使用模板驱动,我想出了这个解决方案:

pairwise() 成对()

<mat-select
    [(ngModel)]="value"
    name="someName"
    multiple="true"
    (selectionChange)="mySubject.next($event.value)"
>

And on the other side, when subscribing to the subject:另一方面,订阅主题时:


this.mySubject.pipe(startWith(null), pairwise()).subscribe({
    next: (values: number[]) => {
        const previousValue = values[0];
        const currentValue = values[1];

        // previousValue will be null on first call
        const newValue = previousValue === null ? 
            currentValue[0] : currentValue.find((value: number) => !previousValue.includes(value));
    }
)


startWith is there because the subject will not emit any value until it has a previous AND a current value. startWith存在是因为主题不会发出任何值,直到它有一个先前的 AND 一个当前值。

You could have use @DaggeJ's solution along with the Template Driven froms as below.您可以使用@DaggeJ 的解决方案以及模板驱动的 froms,如下所示。

<mat-select
    [(ngModel)]="value"
    #mySelect="ngModel"
    name="someName"
    multiple="true"">
    <mat-option
        *ngFor="let val of values"
        [value]="val"
    >
        {{ val }}
    </mat-option>
</mat-select>
@ViewChild('mySelect') mySelect: FormControl;
public ngAfterViewInit() {
    this.mySelect.valueChanges.pipe(pairwise()).subscribe(([prev, next]: [any, any]) => {
       console.log(prev + ' -> ' + next);
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM