Valor predeterminado de las opciones desplegables de Angular 2


115

En Angular 1, podría seleccionar la opción predeterminada para un cuadro desplegable usando lo siguiente:

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

En Angular 2 tengo:

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

¿Cómo podría seleccionar una opción predeterminada dado que los datos de mi opción son:

[{name: 'arm'}, {name: 'back'}, {name:'leg'}]y mi valor predeterminado es back?

Respuestas:


77

Agregue un enlace a la selectedpropiedad, como este:

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

4
Eso no parece funcionar, mirando mi opción seleccionada, no tiene ningún tipo de indicación seleccionada
— ClickThisNick

@ClickThisNick Funcionó cuando lo probé. Vea este plnkr . Cuando termina de cargarse, el menú desplegable de selección muestra "dos" aunque el valor predeterminado normal sería el primer elemento ("uno").
— Douglas

2
La diferencia con el código en @Douglas plnr es que no tiene un [(ngModel)]enlace, por lo tanto, escucha el [selected]enlace en el plnkr y no en el código del OP (vea mi respuesta para obtener un enlace a un plnr bifurcado que explica este efecto)
— Matthijs

2
Uso de formularios dinámicos: uso de formularios selected="workout.name == 'back'"reactivos:[selected]=workout.name == 'back'
— fidev

@fidev, tienes una gran respuesta, y era exactamente lo que estaba buscando. Solo observe que a su ejemplo de formularios reactivos les falta el ". Usé su código con otra variable como esta[selected]="workout.name == exercise.name"
— Alfa Bravo

48

Si asigna el valor predeterminado ay selectedWorkoutusa [ngValue](que permite usar objetos como valor; de lo contrario, solo se admiten cadenas), entonces debería hacer lo que quiera:

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

Asegúrese de que el valor que asigna selectedWorkoutsea ​​la misma instancia que la utilizada en workouts. No se reconocerá otra instancia de objeto, incluso con las mismas propiedades y valores. Solo se comprueba la identidad del objeto.

actualizar

Soporte agregado angular para compareWith, que hace que sea más fácil establecer el valor predeterminado cuando [ngValue]se usa (para valores de objeto)

De los documentos 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;
}

De esta manera, se puede establecer una instancia de objeto diferente (nueva) como valor predeterminado y compareFnse usa para determinar si deben considerarse iguales (por ejemplo, si la idpropiedad es la misma.


2
si tienes tiempo, ¿podrías hacer un plunkr por esto? Por alguna razón, cuando lo intento, $ event aparece como un evento y no como un objeto. Si cambio event a event.target.value, el valor aparece como una cadena como '[object]'
— crh225

Supongo que sería más útil si intentas crear un Plunker que permita reproducir tu problema ;-) Quizás estás usando en [value]lugar de [ngValue]o tu código de alguna manera hace que el valor se convierta en una cadena.
— Günter Zöchbauer

¿Qué hacen c1e c2indican en compareFn? Y también, ¿cómo funciona la evaluación en el cuerpo funcional?
— DongBin Kim

El valor selectedCountriesycountry
— Günter Zöchbauer

1
Lo hice funcionar gracias a la primera parte de esta respuesta.
— The Sharp Ninja

35

simplemente establezca el valor del modelo en el valor predeterminado que desea así:

selectedWorkout = 'back'

Creé una bifurcación de plnkr de @Douglas aquí para demostrar las diversas formas de obtener el comportamiento deseado en angular2.


1
para que esto funcione para mí (en angular 4) también tuve que establecer [ngValue] = "val". Sin embargo, mi fuente de elementos no era una matriz de objetos, sino solo una matriz de cadenas. <select [(ngModel)]="selectedTimeFrame"> <option *ngFor="let val of timeFrames" [ngValue]="val">val</option> </select>
— S. Robijns

33

Agregue este código en la posición o de la lista de selección.

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


1
¿Cuál es el propósito de establecer [ngValue] en indefinido?
— bluePearl

1
Esta debería ser la respuesta aceptada. Establecer [ngValue] en undefined maneja correctamente tener un valor predeterminado seleccionado cuando el 'select' se procesa por primera vez.
— Max

De acuerdo, esta es la respuesta correcta. Le permite usar la opción en la posición 0
— mobiusinversion

@bluePearl, el modelo 'SelectedWorkout' comienza como 'indefinido' si no le asigna nada. Entonces ese debe ser el valor del elemento predeterminado.
— Richard Aguirre

Esta es la mejor respuesta
— Richard Aguirre

20

Puedes acercarte de esta manera:

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

o de esta manera:

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

o puede establecer el valor predeterminado de esta manera:

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

o

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

14

Utilice el índice para mostrar el primer valor como predeterminado

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

5

Según https://angular.io/api/forms/SelectControlValueAccessor , solo necesita lo siguiente:

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

4

Luché un poco con este, pero terminé con la siguiente solución ... tal vez ayude a alguien.

Plantilla HTML:

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

Componente:

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

3

Completamente desarrollando otras publicaciones, esto es lo que funciona en el inicio rápido de Angular2,

Para establecer el DOM predeterminado: junto con *ngFor, use una declaración condicional en el atributo <option>'s selected.

Para configurar el Control valor predeterminado de: use su argumento de constructor. De lo contrario, antes de un cambio cuando el usuario vuelve a seleccionar una opción, que establece el valor del control con el atributo de valor de la opción seleccionada, el valor del control será nulo.

guión:

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

margen:

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

3

Puedes usar eso en [ngModel]lugar de [(ngModel)]y está bien

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

3

Puede hacer lo anterior:

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

En el código anterior, como puede ver, el atributo seleccionado de la opción de repetición se establece al verificar el índice del bucle de repetición de la lista. [attr. <nombre de atributo html>] se utiliza para configurar el atributo html en angular2.

Otro enfoque será establecer el valor del modelo en el archivo mecanografiado como:

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

1

Agregue a la respuesta de @Matthijs, asegúrese de que su selectelemento tenga un nameatributo y namesea ​​único en su plantilla html. Angular 2 está usando el nombre de entrada para actualizar los cambios. Por lo tanto, si hay nombres duplicados o no hay un nombre adjunto al elemento de entrada, el enlace fallará.


0

Agregue la propiedad de enlace seleccionada, pero asegúrese de que sea nula, para otros campos, por ejemplo:

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

Ahora funcionará


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

Si está utilizando un formulario, debe haber un namecampo dentro de la selectetiqueta.

Todo lo que necesita hacer es agregar valuea la optionetiqueta.

selectedWorkout el valor debe ser "back", y listo.


0

Si no desea el enlace bidireccional a través de [(ngModel)], haga esto:

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

¡Acabo de probar mi proyecto en Angular 4 y funciona! El accountsList es una matriz de objetos Account en el que name es una propiedad de Account.

Observación interesante:
[ngValue] = "acct" ejerce el mismo resultado que [ngValue] = "acct.name".
¡No sé cómo lo logra Angular 4!


0

Paso: 1 Crear propiedades declarar clase

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

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

Potencia: 2 Su clase de componente

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

Paso: 3 Ver archivo .html

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

Salida:

ingrese la descripción de la imagen aquí


0

Para mí, defino algunas propiedades:

disabledFirstOption = true;

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

Luego en el constructor y ngOnInit

constructor() {
    this.disabledFirstOption = false;
}

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

Y en la plantilla agrego esto como la primera opción dentro del elemento de selección

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

Si permite seleccionar la primera opción, simplemente puede eliminar el uso de la propiedad disabledFirstOption


0

En mi caso, aquí this.selectedtestSubmitResultViewse establece con un valor predeterminado en función de las condiciones y una variable testSubmitResultViewdebe ser una y la misma que testSubmitResultView. Esto de hecho funcionó para mí

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

Para más información,

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

-1

Me enfrenté a este problema antes y lo solucioné con una solución alternativa simple

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

Luego, en su component.ts puede detectar la opción seleccionada por

gotit(name:string) {
//Use it from hare 
console.log(name);
}

-1

funciona muy bien como se ve a continuación:

<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

Solo necesita poner el ngModel y el valor que desea seleccionar:

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.