Параметры раскрывающегося списка Angular 2 Значение по умолчанию

115

В Angular 1 я мог выбрать вариант по умолчанию для раскрывающегося списка, используя следующее:

<select 
    data-ng-model="carSelection"
    data-ng-options = "x.make for x in cars" data-ng-selected="$first">
</select>

В Angular 2 у меня есть:

<select class="form-control" [(ngModel)]="selectedWorkout" (ngModelChange)="updateWorkout($event)">
    <option *ngFor="#workout of workouts">{{workout.name}}</option>
</select>

Как я могу выбрать вариант по умолчанию, учитывая мои данные о параметрах:

[{name: 'arm'}, {name: 'back'}, {name:'leg'}]и мое значение по умолчанию включено back?

ClickThisNick
источник

Ответы:

77

Добавьте привязку к selectedсвойству, например:

<option *ngFor="#workout of workouts" 
    [selected]="workout.name == 'back'">{{workout.name}}</option>
Дуглас
источник
4
Похоже, что это не работает, глядя на мой выбранный вариант, у него нет какой-либо выбранной индикации
ClickThisNick
@ClickThisNick Это сработало, когда я его тестировал. См. Этот plnkr . Когда загрузка завершается, в раскрывающемся списке выбора отображается «два», хотя обычно по умолчанию будет первый элемент («один»).
Дуглас
2
Разница с кодом в @Douglas plnr заключается в том, что он не имеет [(ngModel)]привязки, поэтому он прослушивает [selected]привязку в plnkr, а не в коде OP (см. Мой ответ для ссылки на разветвленный plnr, который объясняет этот эффект)
Matthijs
2
Использование динамических форм: Использование selected="workout.name == 'back'"реактивных форм:[selected]=workout.name == 'back'
fidev,
@fidev, у вас отличный ответ, и это именно то, что я искал. Просто посмотрите, что в вашем примере реактивных форм отсутствует расширение ". Я использовал ваш код с другой такой переменной[selected]="workout.name == exercise.name"
Alfa Bravo
48

Если вы назначаете значение по умолчанию selectedWorkoutи используете [ngValue](что позволяет использовать объекты в качестве значения - в противном случае поддерживается только строка), тогда он должен просто делать то, что вы хотите:

<select class="form-control" name="sel" 
    [(ngModel)]="selectedWorkout" 
    (ngModelChange)="updateWorkout($event)">
  <option *ngFor="let workout of workouts" [ngValue]="workout">
    {{workout.name}}
  </option>
</select>

Убедитесь, что значение, которое вы назначаете, selectedWorkoutсовпадает с экземпляром, используемым в workouts. Другой экземпляр объекта даже с такими же свойствами и значениями не распознается. Проверяется только идентичность объекта.

Обновить

Добавлена ​​поддержка Angular для compareWith, что упрощает установку значения по умолчанию при [ngValue]использовании (для значений объектов)

Из документов https://angular.io/api/forms/SelectControlValueAccessor

<select [compareWith]="compareFn"  [(ngModel)]="selectedCountries">
    <option *ngFor="let country of countries" [ngValue]="country">
        {{country.name}}
    </option>
</select>
compareFn(c1: Country, c2: Country): boolean {
    return c1 && c2 ? c1.id === c2.id : c1 === c2;
}

Таким образом, другой (новый) экземпляр объекта может быть установлен в качестве значения по умолчанию и compareFnиспользуется для определения того, следует ли считать их равными (например, если idсвойство такое же.

Гюнтер Цохбауэр
источник
2
если есть время, можешь сделать для этого плункер? По какой-то причине, когда я пробую, $ event воспринимается как событие, а не как объект. Если я изменю событие на event.target.value, значение будет
выглядеть
Думаю, было бы более полезно, если бы вы попытались создать Plunker, который позволяет воспроизвести вашу проблему ;-) Возможно, вы используете [value]вместо, [ngValue]или ваш код каким-то образом заставляет значение преобразовываться в строку.
Günter Zöchbauer
Что делать c1и c2указывать в compareFn? А также как работает оценка в теле функции?
DongBin Kim
Значение selectedCountriesиcountry
Günter Zöchbauer
1
У меня все заработало благодаря первой части этого ответа.
The Sharp Ninja
35

просто установите для модели значение по умолчанию, которое вы хотите, например:

selectedWorkout = 'back'

Я создал вилку plnkr @Douglas' здесь , чтобы продемонстрировать различные способы , чтобы получить желаемое поведение в angular2.

Matthijs
источник
1
чтобы это работало для меня (в angular 4) мне также пришлось установить [ngValue] = "val". Мой itemssource был не массивом объектов, а просто массивом строк. <select [(ngModel)]="selectedTimeFrame"> <option *ngFor="let val of timeFrames" [ngValue]="val">val</option> </select>
С. Робейнс
33

Добавьте этот Код в позицию o в списке выбора.

<option [ngValue]="undefined" selected>Select</option>

Махеш
источник
1
какова цель установки [ngValue] в значение undefined?
bluePearl
1
Это должен быть принятый ответ. Установка [ngValue] в undefined правильно обрабатывает выбор значения по умолчанию при первом рендеринге 'select'.
Макс
Согласен, это правильный ответ. Позволяет использовать опцию в позиции 0
mobiusinversion
@bluePearl модель 'SelectedWorkout' начинается как 'undefined', если вы не устанавливаете для нее ничего. Тогда это должно быть de значение элемента по умолчанию.
Ричард Агирре,
Это лучший ответ
Ричард Агирре
20

Можно подойти так:

<option *ngFor="let workout of workouts" [value]="workout.name">{{workout.name}}</option>

или так:

  <option *ngFor="let workout of workouts" [attr.value]="workout.name" [attr.selected]="workout.name == 'leg' ? true : null">{{workout.name}}</option>

или вы можете установить значение по умолчанию следующим образом:

<option [value]="null">Please Select</option>
<option *ngFor="let workout of workouts" [value]="workout.name">{{workout.name}}</option>

или

<option [value]="0">Please Select</option>
<option *ngFor="let workout of workouts" [value]="workout.name">{{workout.name}}</option>
Анил Самал
источник
14

Используйте индекс, чтобы показать первое значение по умолчанию

<option *ngFor="let workout of workouts; #i = index" [selected]="i == 0">{{workout.name}}</option>
Саджит Мантарат
источник
5

Согласно https://angular.io/api/forms/SelectControlValueAccessor вам просто нужно следующее:

theView.html:

<select [compareWith]="compareFn"  [(ngModel)]="selectedCountries">
    <option *ngFor="let country of countries" [ngValue]="country">
        {{country.name}}
    </option>
</select>

theComponent.ts

import { SelectControlValueAccessor } from '@angular/forms';
    compareFn(c1: Country, c2: Country): boolean {
    return c1 && c2 ? c1.id === c2.id : c1 === c2;
}
azatprog
источник
4

Немного боролся с этим, но в итоге получил следующее решение ... может быть, это кому-то поможет.

HTML-шаблон:

<select (change)="onValueChanged($event.target)">
    <option *ngFor="let option of uifOptions" [value]="option.value" [selected]="option == uifSelected ? true : false">{{option.text}}</option>
</select>

Составная часть:

import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';    
export class UifDropdownComponent implements OnInit {
    @Input() uifOptions: {value: string, text: string}[];
    @Input() uifSelectedValue: string = '';
    @Output() uifSelectedValueChange:EventEmitter<string> = new EventEmitter<string>();
    uifSelected: {value: string, text: string} = {'value':'', 'text':''};

    constructor() { }

    onValueChanged(target: HTMLSelectElement):void {
        this.uifSelectedValue = target.value;
        this.uifSelectedValueChange.emit(this.uifSelectedValue);
    }

    ngOnInit() {
        this.uifSelected = this.uifOptions.filter(o => o.value == 
        this.uifSelectedValue)[0];
    }
}
Johnb
источник
3

Вот что работает в кратком руководстве Angular2, полностью уточняя другие сообщения,

Чтобы установить DOM default: вместе с *ngFor, используйте условный оператор в атрибуте <option>'s selected.

Чтобы установить значение по Controlумолчанию: используйте аргумент конструктора. В противном случае перед изменением, когда пользователь повторно выбирает параметр, который устанавливает значение элемента управления с атрибутом значения выбранного параметра, значение элемента управления будет нулевым.

сценарий:

import {ControlGroup,Control} from '@angular/common';
...
export class MyComponent{
  myForm: ControlGroup;
  myArray: Array<Object> = [obj1,obj2,obj3];
  myDefault: Object = myArray[1]; //or obj2

  ngOnInit(){ //override
    this.myForm = new ControlGroup({'myDropdown': new Control(this.myDefault)});
  }
  myOnSubmit(){
    console.log(this.myForm.value.myDropdown); //returns the control's value 
  }
}

разметка:

<form [ngFormModel]="myForm" (ngSubmit)="myOnSubmit()">
  <select ngControl="myDropdown">
    <option *ngFor="let eachObj of myArray" selected="eachObj==={{myDefault}}"
            value="{{eachObj}}">{{eachObj.myText}}</option>
  </select>
  <br>
  <button type="submit">Save</button>
</form>
BeatriceThalo
источник
3

Вы можете использовать это [ngModel]вместо, [(ngModel)]и это нормально

<select class="form-control" **[ngModel]="selectedWorkout"** (ngModelChange)="updateWorkout($event)">
   <option *ngFor="#workout of workouts">{{workout.name}}</option>
</select>
Saeed
источник
3

Вы можете сделать как указано выше:

<select class="form-control" 
        [(ngModel)]="selectedWorkout" 
        (ngModelChange)="updateWorkout($event)">
    <option *ngFor="#workout of workouts;
                    let itemIndex = index"
            [attr.selected]="itemIndex == 0">
    {{workout.name}}
    </option>
</select>

В приведенном выше коде, как вы можете видеть, выбранный атрибут повторяющейся опции устанавливается при проверке индекса повторяющегося цикла списка. [attr. <имя атрибута html>] используется для установки атрибута html в angular2.

Другой подход заключается в установке значения модели в файле машинописного текста как:

this.selectedWorkout = this.workouts.length > 0
                       ? this.workouts[0].name
                       : 'No data found';//'arm'
Пранав Лабхе
источник
1

Добавьте к ответу @Matthijs, убедитесь, что у вашего selectэлемента есть nameатрибут и nameон уникален в вашем шаблоне html. Angular 2 использует имя входа для обновления изменений. Таким образом, если есть повторяющиеся имена или нет имени, прикрепленного к элементу ввода, привязка не будет выполнена.

Вэй Сюй
источник
0

Добавьте выбранное свойство привязки, но убедитесь, что оно равно null, для других полей, например:

<option *ngFor="#workout of workouts" [selected]="workout.name =='back' ? true: null">{{workout.name}}</option>

Теперь будет работать

Jcoder
источник
0
<select class="form-control" name='someting' [ngModel]="selectedWorkout" (ngModelChange)="updateWorkout($event)">
    <option value="{{workout.name}}" *ngFor="#workout of workouts">{{workout.name}}</option>
</select>

Если вы используете форму, nameвнутри selectтега должно быть поле .

Все, что вам нужно сделать, это просто добавить valueв optionтег.

selectedWorkout значение должно быть "назад", и все готово.

Вивек Доши
источник
0

Если вам не нужна двусторонняя привязка через [(ngModel)], сделайте следующее:

<select (change)="selectedAccountName = $event.target.value">
  <option *ngFor="let acct of accountsList" [ngValue]="acct">{{ acct.name }}</option>
</select>

Только что протестировал мой проект на Angular 4, и он работает! AccountList - это массив объектов Account, имя которого является свойством Account.

Интересное наблюдение:
[ngValue] = "acct" дает тот же результат, что и [ngValue] = "acct.name".
Не знаю, как это удается в Angular 4!

Дэниел С. Дэн
источник
0

Шаг: 1 Создайте свойства объявления класса

export class Task {
    title: string;
    priority: Array<any>;
    comment: string;

    constructor() {
        this.title      = '';
        this.priority   = [];
        this.comment    = '';
     }
}

Стебель: 2 Класс вашего компонента

import { Task } from './task';

export class TaskComponent implements OnInit {
  priorityList: Array<any> = [
    { value: 0, label: '✪' },
    { value: 1, label: '★' },
    { value: 2, label: '★★' },
    { value: 3, label: '★★★' },
    { value: 4, label: '★★★★' },
    { value: 5, label: '★★★★★' }
  ];
  taskModel: Task           = new Task();

  constructor(private taskService: TaskService) { }
  ngOnInit() {
    this.taskModel.priority     = [3]; // index number
  }
}

Шаг: 3 Просмотрите файл .html

<select class="form-control" name="priority" [(ngModel)]="taskModel.priority"  required>
    <option *ngFor="let list of priorityList" [value]="list.value">
      {{list.label}}
    </option>
</select>

Вывод:

введите описание изображения здесь

Рам Пукар
источник
0

Для себя я определяю некоторые свойства:

disabledFirstOption = true;

get isIEOrEdge(): boolean {
    return /msie\s|trident\/|edge\//i.test(window.navigator.userAgent)
}

Затем в конструкторе и ngOnInit

constructor() {
    this.disabledFirstOption = false;
}

ngOnInit() {
    setTimeout(() => {
        this.disabledFirstOption = true;
    });
}

И в шаблоне я добавляю это как первую опцию внутри элемента select

<option *ngIf="isIEOrEdge" [value]="undefined" [disabled]="disabledFirstOption" selected></option>

Если вы разрешите выбрать первый вариант, вы можете просто удалить использование свойства disabledFirstOption

Тинь Данг
источник
0

В моем случае здесь this.selectedtestSubmitResultViewустановлено значение по умолчанию на основе условий, и переменная testSubmitResultViewдолжна быть такой же, как testSubmitResultView. Это действительно сработало для меня

<select class="form-control" name="testSubmitResultView"  [(ngModel)]="selectedtestSubmitResultView" (ngModelChange)="updatetestSubmitResultView($event)">
    <option *ngFor="let testSubmitResultView of testSubmitResultViewArry" [ngValue]="testSubmitResultView" >
        {{testSubmitResultView.testSubmitResultViewName}}
    </option>
</select>

Чтобы получить больше информации,

testSubmitResultViewArry: Array<any> = [];
selectedtestSubmitResultView: string;
    
getTestSubmitResultViewList() {
    try {
        this.examService.getTestSubmitResultViewDetails().subscribe(response => {
            if (response != null && response !== undefined && response.length > 0) {
                response.forEach(x => {
                    if (x.isDeleted === false) {
                        this.testSubmitResultViewArry.push(x);
                    }
                    if (x.isDefault === true) {
                        this.selectedtestSubmitResultView = x;
                    }
                })
            }
        });
    } catch (ex) {
        console.log('Method: getTestSubmitResultViewList' + ex.message);
    }
}
Nɪsʜᴀɴᴛʜ ॐ
источник
-1

Я сталкивался с этой проблемой раньше, и я исправил ее с помощью различных простых способов решения

Для вашего Component.html

      <select class="form-control" ngValue="op1" (change)="gotit($event.target.value)">

      <option *ngFor="let workout of workouts" value="{{workout.name}}" name="op1" >{{workout.name}}</option>

     </select>

Затем в вашем component.ts вы можете определить выбранный вариант с помощью

gotit(name:string) {
//Use it from hare 
console.log(name);
}
Рами Хакам
источник
-1

отлично работает, как показано ниже:

<select class="form-control" id="selectTipoDocumento" formControlName="tipoDocumento" [compareWith]="equals"
          [class.is-valid]="this.docForm.controls['tipoDocumento'].valid &&
           (this.docForm.controls['tipoDocumento'].touched ||  this.docForm.controls['tipoDocumento'].dirty)"
          [class.is-invalid]="!this.docForm.controls['tipoDocumento'].valid &&
           (this.docForm.controls['tipoDocumento'].touched ||  this.docForm.controls['tipoDocumento'].dirty)">
            <option value="">Selecione um tipo</option>
            <option *ngFor="let tipo of tiposDocumento" [ngValue]="tipo">{{tipo?.nome}}</option>
          </select>
Андре Родригес де Соуза
источник
-1

Вам просто нужно указать ngModel и значение, которое вы хотите выбрать:

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>
q2design.net
источник