Valeur par défaut des options de liste déroulante angulaire 2


115

Dans Angular 1, je pourrais sélectionner l'option par défaut pour une liste déroulante en utilisant ce qui suit:

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

Dans Angular 2, j'ai:

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

Comment puis-je sélectionner une option par défaut étant donné que mes données d'option sont:

[{name: 'arm'}, {name: 'back'}, {name:'leg'}]et ma valeur par défaut est back?

Réponses:


77

Ajoutez une liaison à la selectedpropriété, comme ceci:

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

4
Cela ne semble pas fonctionner, en regardant l'option sélectionnée, il n'y a aucune sorte d'indication sélectionnée
ClickThisNick

@ClickThisNick Cela a fonctionné lorsque je l'ai testé. Voir ce plnkr . Une fois le chargement terminé, la liste déroulante de sélection affiche «deux» même si la valeur par défaut normale serait le premier élément («un»).
Douglas

2
La différence avec le code dans le plnr @Douglas est qu'il n'a pas de [(ngModel)]liaison donc il écoute la [selected]liaison dans le plnkr et non dans le coden de l'OP (voir ma réponse pour un lien vers un plnr fourchu qui explique cet effet)
Matthijs

2
Utilisation des formulaires dynamiques: Utilisation des formulaires selected="workout.name == 'back'"réactifs:[selected]=workout.name == 'back'
fidev

@fidev, vous avez une excellente réponse, et c'était exactement ce que je cherchais. Regardez simplement que votre exemple de formulaires réactifs ne contient pas le fichier ". J'ai utilisé votre code avec une autre variable comme celle-ci[selected]="workout.name == exercise.name"
Alfa Bravo

48

Si vous attribuez la valeur par défaut à selectedWorkoutet utilisez [ngValue](ce qui permet d'utiliser des objets comme valeur - sinon seule la chaîne est prise en charge), alors il devrait simplement faire ce que vous voulez:

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

Assurez-vous que la valeur que vous attribuez selectedWorkoutest la même instance que celle utilisée dans workouts. Une autre instance d'objet même avec les mêmes propriétés et valeurs ne sera pas reconnue. Seule l'identité de l'objet est vérifiée.

mettre à jour

Prise en charge angulaire ajoutée pour compareWith, qui facilite la définition de la valeur par défaut lorsqu'elle [ngValue]est utilisée (pour les valeurs d'objet)

À partir de la documentation 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 cette façon, une (nouvelle) instance d'objet différente peut être définie comme valeur par défaut et compareFnest utilisée pour déterminer si elles doivent être considérées comme égales (par exemple, si la idpropriété est la même.


2
si vous avez le temps, pourriez-vous faire un plunkr pour ça? Pour une raison quelconque, lorsque je l'essaye, $ event apparaît comme un événement et non comme un objet. Si je change d'événement en event.target.value, la valeur apparaît sous la forme d'une chaîne comme '[object]'
crh225

Je suppose que ce serait plus utile si vous essayez de créer un Plunker qui permet de reproduire votre problème ;-) Peut-être que vous utilisez à la [value]place de [ngValue]ou votre code provoque en quelque sorte la conversion de la valeur en chaîne.
Günter Zöchbauer

Que font c1et c2indiquent dans compareFn? Et aussi, comment fonctionne l'évaluation dans le corps de fonction?
DongBin Kim

La valeur selectedCountriesetcountry
Günter Zöchbauer

1
Je l'ai fait fonctionner grâce à la première partie de cette réponse.
The Sharp Ninja

35

définissez simplement la valeur du modèle sur la valeur par défaut que vous souhaitez comme ceci:

selectedWorkout = 'back'

J'ai créé un fork du plnkr de @Douglas ici pour démontrer les différentes manières d'obtenir le comportement souhaité dans angular2.


1
pour que cela fonctionne pour moi (en angulaire 4), j'ai également dû définir [ngValue] = "val". Mon itemssource n'était pas un tableau d'objets mais juste un tableau de chaînes. <select [(ngModel)]="selectedTimeFrame"> <option *ngFor="let val of timeFrames" [ngValue]="val">val</option> </select>
S. Robijns

33

Ajoutez ce code à la position o de la liste de sélection.

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


1
quel est le but de définir [ngValue] sur undefined?
bluePearl

1
Cela devrait être la réponse acceptée. La définition de [ngValue] sur undefined gère correctement la sélection d'une valeur par défaut lors du premier rendu de 'select'.
Max

D'accord, c'est la bonne réponse. Vous permet d'utiliser l'option à la position 0
mobiusinversion

@bluePearl le modèle 'SelectedWorkout' commence par 'indéfini' si vous ne le définissez pas sur rien, alors cela doit être la valeur de l'élément par défaut.
Richard Aguirre le

C'est la meilleure réponse
Richard Aguirre

20

Vous pouvez aborder de cette façon:

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

ou de cette façon:

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

ou vous pouvez définir la valeur par défaut de cette façon:

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

ou

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

14

Utiliser l'index pour afficher la première valeur par défaut

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

5

Selon https://angular.io/api/forms/SelectControlValueAccessor, vous avez juste besoin de ce qui suit:

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

J'ai eu un peu de mal avec celui-ci, mais j'ai fini avec la solution suivante ... peut-être que cela aidera quelqu'un.

Modèle HTML:

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

Composant:

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

Complètement étoffé d'autres articles, voici ce qui fonctionne dans le démarrage rapide Angular2,

Pour définir la valeur par défaut du DOM: avec *ngFor, utilisez une instruction conditionnelle dans l' attribut <option>'s selected.

Pour définir la Controlvaleur par défaut de: utilisez son argument constructeur. Sinon, avant une modification lorsque l'utilisateur sélectionne à nouveau une option, qui définit la valeur du contrôle avec l'attribut value de l'option sélectionnée, la valeur de contrôle sera nulle.

scénario:

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

balisage:

<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

Vous pouvez utiliser cela [ngModel]au lieu de [(ngModel)]et c'est ok

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

3

Vous pouvez faire comme ci-dessus:

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

Dans le code ci-dessus, comme vous pouvez le voir, l'attribut sélectionné de l'option de répétition est défini lors de la vérification de l'index de la boucle répétée de la liste. [attr. <nom d'attribut html>] est utilisé pour définir l'attribut html dans angular2.

Une autre approche consistera à définir la valeur du modèle dans un fichier dactylographié comme suit:

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

1

Ajoutez à la réponse de @Matthijs, veuillez vous assurer que votre selectélément a un nameattribut et qu'il nameest unique dans votre modèle html. Angular 2 utilise le nom d'entrée pour mettre à jour les modifications. Ainsi, s'il existe des noms en double ou s'il n'y a pas de nom attaché à l'élément d'entrée, la liaison échouera.


0

Ajoutez la propriété de liaison sélectionnée, mais assurez-vous de la rendre nulle, pour les autres champs, par exemple:

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

Maintenant ça va marcher


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 vous utilisez le formulaire, il devrait y avoir un namechamp à l'intérieur de la selectbalise.

Tout ce que vous avez à faire est simplement d'ajouter valueau optiontag.

selectedWorkout la valeur doit être "retour", et c'est fait.


0

Si vous ne voulez pas la liaison bidirectionnelle via [(ngModel)], procédez comme suit:

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

Je viens de tester mon projet sur Angular 4 et ça marche! Le accountsList est un tableau d'objets Account dans lequel name est une propriété de Account.

Observation intéressante:
[ngValue] = "acct" exerce le même résultat que [ngValue] = "acct.name".
Je ne sais pas comment Angular 4 y parvient!


0

Étape: 1 Créer des propriétés déclarer la classe

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

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

Potence: 2 votre classe de composant

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

Étape: 3 Afficher le fichier .html

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

Production:

entrez la description de l'image ici


0

Pour moi, je définis quelques propriétés:

disabledFirstOption = true;

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

Puis dans le constructeur et ngOnInit

constructor() {
    this.disabledFirstOption = false;
}

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

Et dans le modèle, j'ajoute ceci comme première option à l'intérieur de l'élément select

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

Si vous autorisez la sélection de la première option, vous pouvez simplement supprimer l'utilisation de la propriété disabledFirstOption


0

Dans mon cas, ici this.selectedtestSubmitResultViewest défini avec une valeur par défaut basée sur des conditions et une variable testSubmitResultViewdoit être identique à testSubmitResultView. Cela a en effet fonctionné pour moi

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

Pour plus d'informations,

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

J'ai déjà rencontré ce problème et je l'ai résolu avec une solution de contournement simple

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

Ensuite, dans votre component.ts, vous pouvez détecter l'option sélectionnée en

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

-1

fonctionne très bien comme vu ci-dessous:

<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

Il vous suffit de mettre le ngModel et la valeur que vous souhaitez sélectionner:

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.