Angular Материал: мат-выберите не выбрать значение по умолчанию
У меня есть mat-select, где в качестве параметров указаны все объекты, определенные в массиве. Я пытаюсь установить значение по умолчанию для одного из параметров, однако оно остается выбранным при отображении страницы.
Мой машинописный файл содержит:
public options2 = [
{"id": 1, "name": "a"},
{"id": 2, "name": "b"}
]
public selected2 = this.options2[1].id;
Мой HTML файл содержит:
<div>
<mat-select
[(value)]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
Я попытался установить selected2
и value
в mat-option
как для объекта, так и для его id, и попытался использовать оба [(value)]
и [(ngModel)]
в mat-select
, но ни один из них не работает.
Я использую материал версии 2.0.0-бета .10
Ответы
Ответ 1
Используйте привязку для значения в вашем шаблоне.
value="{{ option.id }}"
должен быть
[value]="option.id"
И в выбранном вами значении используйте ngModel
вместо value
.
<mat-select [(value)]="selected2">
должен быть
<mat-select [(ngModel)]="selected2">
Полный код:
<div>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</div>
На стороне примечания от версия 2.0.0-beta.12 select > теперь принимает элемент mat-form-field
в качестве родительского элемента, поэтому он согласуется с другими элементами управления элементами материала. Замените элемент div
элементом mat-form-field
после обновления.
<mat-form-field>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</mat-form-field>
Ответ 2
Используйте compareWith
, A для сравнения значений параметров с выбранными значениями. см. здесь: https://material.angular.io/components/select/api#MatSelect
Для объекта следующей структуры:
listOfObjs = [{ name: 'john', id: '1'}, { name: 'jimmy', id: '2'},...]
Определите разметку следующим образом:
<mat-form-field>
<mat-select
[compareWith]="compareObjects"
[(ngModel)]="obj">
<mat-option *ngFor="let obj of listOfObjs" [value]="obj">
{{ obj.name }}
</mat-option>
</mat-select>
</mat-form-field>
И определите функцию сравнения следующим образом:
compareObjects(o1: any, o2: any): boolean {
return o1.name === o2.name && o1.id === o2.id;
}
Ответ 3
Я использую Angular 5 и реактивные формы с mat-select и не смог получить ни одно из вышеуказанных решений для отображения начального значения.
Мне пришлось добавить [compareWith], чтобы иметь дело с различными типами, используемыми в компоненте mat-select. Внутренне кажется, что mat-select использует массив для хранения выбранного значения. Это может позволить одному и тому же коду работать с несколькими вариантами выбора, если этот режим включен.
Angular Select Control Doc
Вот мое решение:
Конструктор форм для инициализации элемента управления формы:
this.formGroup = this.fb.group({
country: new FormControl([ this.myRecord.country.id ] ),
...
});
Затем реализуйте функцию сравнения с вашим компонентом:
compareIds(id1: any, id2: any): boolean {
const a1 = determineId(id1);
const a2 = determineId(id2);
return a1 === a2;
}
Затем создайте и экспортируйте функцию defineId (мне пришлось создать отдельную функцию, чтобы mat-select мог ее использовать):
export function determineId(id: any): string {
if (id.constructor.name === 'array' && id.length > 0) {
return '' + id[0];
}
return '' + id;
}
Наконец добавьте атрибут CompareWith к вашему mat-select:
<mat-form-field hintLabel="select one">
<mat-select placeholder="Country" formControlName="country"
[compareWith]="compareIds">
<mat-option>None</mat-option>
<mat-option *ngFor="let country of countries" [value]="country.id">
{{ country.name }}
</mat-option>
</mat-select>
</mat-form-field>
Ответ 4
Вы должны привязать его как [value]
в mat-option
как показано ниже,
<mat-select placeholder="Panel color" [(value)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">
{{ option.name }}
</mat-option>
</mat-select>
LIVE DEMO
Ответ 5
Как уже упоминалось в Angular 6 с использованием ngModel в реактивных формах, устаревает (и удаляется в Angular 7), поэтому я изменил шаблон и компонент следующим образом.
Шаблон:
<mat-form-field>
<mat-select [formControl]="filter" multiple
[compareWith]="compareFn">
<mat-option *ngFor="let v of values" [value]="v">{{v.label}}</mat-option>
</mat-select>
</mat-form-field>
Основные части компонента (onChanges
и другие детали опущены):
interface SelectItem {
label: string;
value: any;
}
export class FilterComponent implements OnInit {
filter = new FormControl();
@Input
selected: SelectItem[] = [];
@Input()
values: SelectItem[] = [];
constructor() { }
ngOnInit() {
this.filter.setValue(this.selected);
}
compareFn(v1: SelectItem, v2: SelectItem): boolean {
return compareFn(v1, v2);
}
}
function compareFn(v1: SelectItem, v2: SelectItem): boolean {
return v1 && v2 ? v1.value === v2.value : v1 === v2;
}
Обратите внимание на this.filter.setValue(this.selected) в ngOnInit
выше.
Кажется, он работает в Angular 6.
Ответ 6
Вы можете просто реализовать свою собственную функцию сравнения
[compareWith]="compareItems"
Смотрите также документ. Таким образом, полный код будет выглядеть так:
<div>
<mat-select
[(value)]="selected2" [compareWith]="compareItems">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
и в файле Typescript:
compareItems(i1, i2) {
return i1 && i2 && i1.id===i2.id;
}
Ответ 7
Я сделал это так же, как в этих примерах. Пытался установить значение mat-select равным значению одной из опций mat. Но не удалось.
Моя ошибка заключалась в том, чтобы сделать [(value)] = "someNumberVariable" для переменной числового типа, в то время как переменные в mat-options были строками. Даже если они выглядят одинаково в шаблоне, он не выберет эту опцию.
Как только я проанализировал строку someNumberVariable, все было в порядке.
Поэтому, похоже, вам нужно, чтобы значения mat-select и mat-option не только были одинаковыми (если вы представляете числа), но и позволяли им иметь тип string.
Ответ 8
Мое решение немного сложнее и проще.
<div>
<mat-select
[placeholder]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
Я просто использовал местозаполнитель. Цвет заполнитель материала по умолчанию light gray
. Чтобы он выглядел как опция выбрана, я просто манипулировал CSS следующим образом:
::ng-deep .mat-select-placeholder {
color: black;
}
Ответ 9
Решение для меня было:
<mat-form-field>
<mat-select #monedaSelect formControlName="monedaDebito" [attr.disabled]="isLoading" [placeholder]="monedaLabel | async ">
<mat-option *ngFor="let moneda of monedasList" [value]="moneda.id">{{moneda.detalle}}</mat-option>
</mat-select>
TS:
@ViewChild('monedaSelect') public monedaSelect: MatSelect;
this.genericService.getOpciones().subscribe(res => {
this.monedasList = res;
this.monedaSelect._onChange(res[0].id);
});
Используя объект: {id: номер, detalle: строка}
Ответ 10
Попробуй это!
this.selectedObjectList = [{id:1}, {id:2}, {id:3}]
this.allObjectList = [{id:1}, {id:2}, {id:3}, {id:4}, {id:5}]
let newList = this.allObjectList.filter(e => this.selectedObjectList.find(a => e.id == a.id))
this.selectedObjectList = newList
Ответ 11
ОТВЕТ НА УГЛОВОЙ V6 и UP
Поддержка использования входных свойств ngModel и события ngModelChange с директивами формы реактивного и управляемого шаблонами устарела в Angular v6 и будет удалена в Angular v7.
<div>
<mat-select [(value)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</div>
Ответ 12
Сравнение между числом и строкой использует значение false, поэтому приведите выбранное вами значение к строке внутри ngOnInit, и она будет работать.
У меня возникла та же проблема, я заполнил mat-select перечислением, используя
Object.keys(MyAwesomeEnum).filter(k => !isNaN(Number(k)));
и у меня было значение enum, которое я хотел выбрать...
Я потратил несколько часов, пытаясь понять, почему это не работает. И я сделал это сразу после рендеринга всех переменных, используемых в mat-select, коллекции ключей и selected... если у вас есть ["0", "1", "2"] и вы хотите выбрать 1 ( который является числом) 1 == "1" является ложным, и поэтому ничего не выбрано.
Итак, решение состоит в том, чтобы преобразовать выбранное вами значение в строку внутри ngOnInit, и это будет работать.