Valore predefinito delle opzioni a discesa Angular 2


115

In Angular 1 potrei selezionare l'opzione predefinita per una casella a discesa utilizzando quanto segue:

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

In Angular 2 ho:

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

Come posso selezionare un'opzione predefinita dato che i dati delle mie opzioni sono:

[{name: 'arm'}, {name: 'back'}, {name:'leg'}]e il mio valore su cui impostare come predefinito è back?

Risposte:


77

Aggiungi un'associazione alla selectedproprietà, in questo modo:

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

4
Non sembra funzionare, guardando la mia opzione selezionata non ha alcun tipo di indicazione selezionata
ClickThisNick

@ClickThisNick Ha funzionato quando l'ho testato. Vedi questo plnkr . Al termine del caricamento, il menu a discesa di selezione mostra "due" anche se il valore predefinito normale sarebbe il primo elemento ("uno").
Douglas

2
La differenza con il codice nel @Douglas plnr è che non ha un [(ngModel)]binding quindi ascolta il [selected]binding nel plnkr e non nel codice dell'OP (vedi la mia risposta per un collegamento a un plnr biforcuto che spiega questo effetto)
Matthijs

2
Utilizzo dei moduli dinamici: Utilizzo dei moduli selected="workout.name == 'back'"reattivi:[selected]=workout.name == 'back'
fidev

@fidev, hai un'ottima risposta, ed era esattamente quello che stavo cercando. Dai un'occhiata al tuo esempio di moduli reattivi manca il ". Ho usato il tuo codice con un'altra variabile come questa[selected]="workout.name == exercise.name"
Alfa Bravo

48

Se si assegna il valore predefinito a selectedWorkoute si utilizza [ngValue](che consente di utilizzare oggetti come valore - altrimenti è supportata solo la stringa), allora dovrebbe semplicemente fare quello che vuoi:

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

Assicurati che il valore a cui assegni selectedWorkoutsia la stessa istanza di quella utilizzata in workouts. Un'altra istanza di oggetto anche con le stesse proprietà e valori non verrà riconosciuta. Viene verificata solo l'identità dell'oggetto.

aggiornare

Supporto angolare aggiunto per compareWith, che semplifica l'impostazione del valore predefinito quando [ngValue]viene utilizzato (per i valori degli oggetti)

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

In questo modo una diversa (nuova) istanza di oggetto può essere impostata come valore predefinito e compareFnviene utilizzata per capire se devono essere considerati uguali (ad esempio se la idproprietà è la stessa.


2
se hai tempo, potresti fare un plunkr per questo? Per qualche ragione, quando lo provo, $ event si presenta come un evento e non come un oggetto. Se cambio evento in event.target.value, il valore viene visualizzato come una stringa come "[oggetto]"
crh225

Immagino che sarebbe più utile se provassi a creare un Plunker che permetta di riprodurre il tuo problema ;-) Forse stai usando al [value]posto di [ngValue]o il tuo codice in qualche modo fa convertire il valore in una stringa.
Günter Zöchbauer

Cosa fanno c1e c2indicano compareFn? Inoltre, come funziona la valutazione nel corpo della funzione?
DongBin Kim

Il valore selectedCountriesecountry
Günter Zöchbauer

1
Ho funzionato grazie alla prima parte di questa risposta.
The Sharp Ninja

35

imposta semplicemente il valore del modello sul valore predefinito che desideri in questo modo:

selectedWorkout = 'back'

Ho creato un fork del plnkr di @Douglas qui per dimostrare i vari modi per ottenere il comportamento desiderato in angular2.


1
perché questo funzionasse per me (nell'angolo 4) ho anche dovuto impostare [ngValue] = "val". Il mio itemssource però non era un array di oggetti ma solo un array di stringhe. <select [(ngModel)]="selectedTimeFrame"> <option *ngFor="let val of timeFrames" [ngValue]="val">val</option> </select>
S. Robijns

33

Aggiungere questo codice alla posizione o dell'elenco di selezione.

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


1
qual è lo scopo di impostare [ngValue] su undefined?
bluePearl

1
Questa dovrebbe essere la risposta accettata. L'impostazione di [ngValue] su undefined gestisce correttamente la selezione di un valore predefinito al primo rendering di "select".
Max

D'accordo, questa è la risposta corretta. Consente di utilizzare l'opzione alla posizione 0
mobiusinversion

@bluePearl il modello "SelectedWorkout" inizia come "undefined" se non lo si imposta su nulla. Quindi deve essere il valore dell'elemento predefinito.
Richard Aguirre,

Questa è la risposta migliore
Richard Aguirre il

20

Puoi avvicinarti in questo modo:

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

o in questo modo:

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

oppure puoi impostare il valore predefinito in questo modo:

<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

Usa indice per mostrare il primo valore come predefinito

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

5

Secondo https://angular.io/api/forms/SelectControlValueAccessor hai solo bisogno di quanto segue:

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

Ha lottato un po 'con questo, ma è finito con la seguente soluzione ... forse aiuterà qualcuno.

Modello 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 arricchendo altri post, ecco cosa funziona in Angular2 quickstart,

Per impostare il valore predefinito DOM: insieme *ngFor, utilizzare un'istruzione condizionale nel <option>'s selectedattributo.

Per impostare il Controlvalore predefinito di: usa il suo argomento costruttore. In caso contrario, prima di una modifica quando l'utente seleziona nuovamente un'opzione, che imposta il valore del controllo con l'attributo value dell'opzione selezionata, il valore del controllo sarà nullo.

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's value 
  }
}

markup:

<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

Puoi usarlo [ngModel]invece di [(ngModel)]ed è ok

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

3

Puoi fare come sopra:

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

Nel codice sopra come puoi vedere, l'attributo selezionato dell'opzione ripetuta è impostato sul controllo dell'indice del ciclo ripetuto della lista. [attr. <nome attributo html>] viene utilizzato per impostare l'attributo html in angular2.

Un altro approccio sarà l'impostazione del valore del modello nel file dattiloscritto come:

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

1

Aggiungi alla risposta di @Matthijs, assicurati che il tuo selectelemento abbia un nameattributo e che namesia unico nel tuo modello html. Angular 2 utilizza il nome di input per aggiornare le modifiche. Pertanto, se sono presenti nomi duplicati o non è presente alcun nome allegato all'elemento di input, l'associazione fallirà.


0

Aggiungi la proprietà di associazione selezionata, ma assicurati di renderla nulla, per altri campi, ad esempio:

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

Adesso funzionerà


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

Se stai usando il modulo dovrebbe esserci un namecampo all'interno del selecttag.

Tutto quello che devi fare è semplicemente aggiungere valueal optiontag.

selectedWorkout il valore dovrebbe essere "indietro", e il gioco è fatto.


0

Se non desideri l'associazione a 2 vie tramite [(ngModel)], procedi come segue:

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

Ho appena testato il mio progetto su Angular 4 e funziona! AccountList è un array di oggetti Account in cui il nome è una proprietà di Account.

Osservazione interessante:
[ngValue] = "acct" esercita lo stesso risultato di [ngValue] = "acct.name".
Non so come ci riesca Angular 4!


0

Passaggio: 1 Crea proprietà dichiara la classe

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

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

Attacco manubrio: 2 La tua classe di componenti

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

Passaggio: 3 Visualizza file .html

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

Produzione:

inserisci qui la descrizione dell'immagine


0

Per me, definisco alcune proprietà:

disabledFirstOption = true;

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

Quindi nel costruttore e ngOnInit

constructor() {
    this.disabledFirstOption = false;
}

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

E nel modello aggiungo questo come prima opzione all'interno dell'elemento select

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

Se consenti di selezionare la prima opzione, puoi semplicemente rimuovere l'utilizzo della proprietà disabledFirstOption


0

Nel mio caso, qui this.selectedtestSubmitResultViewè impostato con il valore predefinito in base alle condizioni e una variabile testSubmitResultViewdeve essere uguale a testSubmitResultView. Questo effettivamente ha funzionato per me

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

Per maggiori informazioni,

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

Ho affrontato questo problema prima e l'ho risolto con vari metodi semplici

Per il tuo 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>

Quindi nel tuo component.ts puoi rilevare l'opzione selezionata tramite

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

-1

funziona alla grande come mostrato di seguito:

<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

Devi solo inserire ngModel e il valore che desideri selezionare:

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.