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

В 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?

Ответ 1

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

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

Ответ 2

Если вы назначаете значение по умолчанию для 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 одинаковое.

Ответ 3

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

selectedWorkout = 'back'

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

Ответ 4

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

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

Ответ 5

Вы можете подойти так:

<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>

Ответ 6

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

<option *ngFor="let workout of workouts; #i = index" [selected]="i == 0">{{workout.name}}</option>

Ответ 7

Согласно 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;
}

Ответ 8

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

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];
    }
}

Ответ 9

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

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

Ответ 10

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

<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>

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

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

this.selectedWorkout = this.workouts.length > 0
                       ? this.workouts[0].name
                       : 'No data found';//'arm'

Ответ 11

Полностью сглаживая другие сообщения, вот что работает в Angular2 quickstart,

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

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

script:

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 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>

Ответ 12

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

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

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

Ответ 13

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

Ответ 14

<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 Значение должно быть "назад" и выполнено.

Ответ 15

Если вы не хотите привязку 2-way через [(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!

Ответ 16

Шаг: 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>

Вывод:

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

Ответ 17

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

<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>

Ответ 18

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

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

Ответ 19

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

Для вашего 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);
}

Ответ 20

Начнется игра с AngularJS 4 и Typescript, и это сложно. Я использую Angular Reactive Forms (или Model Driven) и имеет компонент Адрес, который содержит поля провинции и страны, которые я хотел бы представить в качестве раскрывающегося списка со значениями по умолчанию. Я следовал ниже

  • Создать адрес .ts модель (адрес)
  • Создать адрес .component.ts (AddressComponent)
  • Создать адрес .component.html (шаблон)
  • Импортируйте AddressComponent в свои модули (т.е. маршрутизатор, если есть)

Модель address.ts выглядит следующим образом


export class Address {
  type: string;
    street: string;
    city: string;
    postalcode: string;
    provinces = ['AB', 'BC', 'MB', 'NB', 'NL', 'NS', 'NT',
            'NU', 'ON', 'PE', 'QC', 'SK', 'YT'];
    countries = ['Canada', 'USA'];
}

Далее адрес .component.ts


import { Component, Input, OnInit } from '@angular/core';
import { FormArray, FormGroup, FormBuilder, Validators } from '@angular/forms';

import { Address } from '../../models/address';

@Component({
  selector: 'address',
  templateUrl: './address.component.html'
})
export class AddressComponent implements OnInit {
  @Input()
  addressForm: FormGroup;
  address = new Address();

  constructor (private fb: FormBuilder){}

  ngOnInit(){
    this.addressForm = this.fb.group({
      type: ['', Validators.required],
      street: [''],
      city: ['', Validators.required],
      postalcode: [''],
      provinces: [this.address.provinces],
      countries: [this.address.countries]
    });
  }
}  

Далее адрес .component.html


<form [formGroup]="addressForm" class="address">
  <div class="form-group">
    <label>Address type</label>
    <input type="text" class="form-control" formControlName="type">
  </div>
  <div class="form-group">
    <label>Street</label>
    <input type="text" class="form-control" formControlName="street">
  </div>
  <div class="form-group">
    <label>City</label>
    <input type="text" class="form-control" formControlName="city">
  </div>
  <div class="form-group">
    <label>Postal code</label>
    <input type="text" class="form-control" (formControlName)="postalcode">
  </div>
  <div class="form-group">
    <label>Province</label>
    <select class="form-control" formControlName="provinces">
      <option *ngFor="let province of address.provinces" [value]="province">
        {{province}}
      </option>
    </select>
  </div>
  <div class="form-group">
    <label>country</label>
    <select class="form-control" formControlName="countries">
      <option *ngFor="let country of address.countries" [value]="country">
        {{country}}
      </option>
    </select>
  </div>
</form>

С тремя выше, я могу сделать адрес самостоятельно, выполнив следующие шаги

  • Обновите app-routing.module.ts, где у меня есть настраиваемые маршруты.
  • Обновите app.module.ts
  • Обновите app.component.ts, чтобы включить адрес в тег маршрутизатора

Обновите app-routing.module.ts


import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { UserRegistrationComponent } from '../user/user-registration.component';

//temporary
import { AddressComponent } from '../address/address.component';

const routes : Routes = [
  { path: 'user/register', component: UserRegistrationComponent },
  { path: 'temp/address', component: AddressComponent }
]

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

Затем app.module.ts импортирует AddressComponent и включает его в массив объявлений конструктора NgModule


import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppRoutingModule } from './modules/app-routing.module'

import { AppComponent }  from './app.component';
import { UserService } from './services/user.service'

import { UserRegistrationComponent } from './user/user-registration.component';

//import temporary
import { AddressComponent } from './address/address.component';

@NgModule({
  imports:      [
    BrowserModule,
    ReactiveFormsModule,
    HttpModule,
    AppRoutingModule
  ],
  declarations: [
    AppComponent,
    UserRegistrationComponent,
    AddressComponent
  ],
  exports : [
  ],
  providers: [
    UserService
  ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

И, наконец, обновите шаблон app.component.ts html, чтобы включить ссылку компонента "Адрес", чтобы мы могли перейти к ней и увидеть форму адреса в действии.


import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <div class="container">
      <h1>Sample</h1>
      <nav>
        <a routerLink="/user/register" routerLinkActive="active">Register User</a><br>
        <a routerLink="/temp/address" routerLinkActive="active">Address</a>
      </nav>
      <router-outlet></router-outlet>
    </div>

  `,
})
export class AppComponent  { name = 'Sample'; }

И это все. Полученная форма адреса выглядит следующим образом:

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

Теперь у меня есть компонент реактивной формы адреса, который я могу вставлять везде, где мне нужно поле адреса. Он действительно много кода для поля адреса. Новые для AngularJS 4 и Typescript, поэтому код может иметь ошибки.

Ответ 21

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

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>