Установить значение ‹mat-select› программно

Я пытаюсь программно установить значение 2 полей <input matInput> abnd <mat-select>. Для ввода текста все работает должным образом, однако для <mat-select> в представлении это поле выглядит так же, как и значение null. Но если я позвоню console.log(productForm.controls['category'].value, он распечатает правильное значение, которое я установил программно. Я что-то упускаю?

Вот код:

конфигурация формы:

productForm = new FormGroup({
    name: new FormControl('', [
        Validators.required
    ]),
    category: new FormControl('', [
        Validators.required
    ]),
});

значение настройки:

ngOnInit() {
    this.productForm.controls['name'].setValue(this.product.name);
        this.productForm.controls['category'].setValue(this.product.category);
    }
}

html:

<mat-form-field>
    <mat-select [formControlName]="'category'"
                [errorStateMatcher]="errorStateMatcher">
        <mat-option *ngFor="let category of categories" [value]="category">
            {{category.name}}
        </mat-option>
    </mat-select>
</mat-form-field>

person TomOw    schedule 14.02.2018    source источник


Ответы (4)


Angular mat-select сравнивает по ссылке этот объект и все доступные объекты в mat-select. В результате не удается выбрать элементы, которые вы установили в поле категории. Следовательно, вы должны реализовать функцию сравнения для сравнения любого из атрибутов элементов списка по своему усмотрению, а затем передать эту функцию в [compareWith] атрибут _4 _. < br /> В заключение, вот снимок окончательной разметки и скрипта:

<mat-form-field>
    <mat-select [formControlName]="category" [compareWith]="compareCategoryObjects">
        <mat-option *ngFor="let category of categories" [value]="category">
            {{category.name}}
        </mat-option>
    </mat-select>
</mat-form-field>

И в классе компонентов:

compareCategoryObjects(object1: any, object2: any) {
    return object1 && object2 && object1.id == object2.id;
}

Теперь он выберет элемент - или элементы, если несколько вариантов выбора - вы установили для поля.

Ссылка:
https://github.com/angular/material2/issues/10214

Рабочий образец:
https://stackblitz.com/edit/angular-material2-issue-t8rp7j

person Hany    schedule 03.01.2019
comment
Это действительно правильный ответ. Принятый ответ OP сработал, потому что OP изменил привязку объекта к mat-select на поле Id, которое имеет тип, который является примитивным типом в Angular. Следовательно, compareWith работает как встроенный в Angular. Если нужно привязать mat-select к объекту, необходимо определить compareWith. В отличие от Java, вам нужно реализовать equals и hashcode, если вы ожидаете, что все будет работать правильно. - person Thomas Carlisle; 04.03.2021

Решил эту проблему, изменив значение <mat-option> с объекта category на его идентификатор.

<mat-form-field>
<mat-select [formControlName]="'category'"
        [errorStateMatcher]="errorStateMatcher">
<mat-option *ngFor="let category of categories" [value]="category.id">
    {{category.name}}
</mat-option>
</mat-select>
</mat-form-field>

и значение настройки:

this.productForm.controls['category'].setValue(this.product.category.id);
person TomOw    schedule 14.02.2018

Чтобы добиться этого с помощью объектов, нужно изменить разметку следующим образом:

<mat-select [formControlName]="'category'"
        [errorStateMatcher]="errorStateMatcher" [compareWith]="compareFn">
<mat-option *ngFor="let category of categories" [value]="category">
    {{category.name}}
</mat-option>
</mat-select>

Тогда в компоненте

compareFn(x: Category, y: Category): boolean {
return x && y ? x.id === y.id : x === y;
}
person joe.coder    schedule 21.02.2018

Я думаю, здесь вам следует использовать FormGroup.setValue.

Согласно вашему коду,

this.productForm.setValue({
name: this.product.name,
category: this.product.category
});

Для получения дополнительной информации см. документацию

person NoughT    schedule 01.03.2019