Opcje rozwijane Angular 2 Wartość domyślna

115

W Angular 1 mogłem wybrać domyślną opcję dla rozwijanej listy, używając:

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

W Angular 2 mam:

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

Jak mogę wybrać opcję domyślną, biorąc pod uwagę moje dane opcji:

[{name: 'arm'}, {name: 'back'}, {name:'leg'}]a moja wartość domyślna to back?

ClickThisNick
źródło

Odpowiedzi:

77

Dodaj powiązanie do selectedwłaściwości, na przykład:

<option *ngFor="#workout of workouts" 
    [selected]="workout.name == 'back'">{{workout.name}}</option>
Douglas
źródło
4
To wydaje się nie działać, patrząc na moją wybraną opcję, nie ma żadnego wybranego wskazania
ClickThisNick
@ClickThisNick Zadziałało, kiedy to przetestowałem. Zobacz ten plnkr . Po zakończeniu ładowania lista rozwijana wyboru pokazuje „dwa”, mimo że normalnym ustawieniem domyślnym byłby pierwszy element („jeden”).
Douglas
2
Różnica w stosunku do kodu w @Douglas plnr polega na tym, że nie ma [(ngModel)]powiązania, więc słucha [selected]wiązania w plnkr a nie w kodzie OP (patrz moja odpowiedź na link do rozwidlonego plnr, który wyjaśnia ten efekt)
Matthijs
2
Korzystanie z formularzy dynamicznych: selected="workout.name == 'back'"Formularze reaktywne używają:[selected]=workout.name == 'back'
fidev
@fidev, masz świetną odpowiedź i właśnie tego szukałem. Wystarczy spojrzeć, że w przykładzie formularzy reaktywnych brakuje rozszerzenia ". Użyłem twojego kodu z inną taką zmienną[selected]="workout.name == exercise.name"
Alfa Bravo
48

Jeśli przypiszesz wartość domyślną selectedWorkouti użyjesz [ngValue](co pozwala na użycie obiektów jako wartości - w przeciwnym razie obsługiwany jest tylko łańcuch), to powinno po prostu zrobić to, co chcesz:

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

Upewnij się, że wartość, do której przypisujesz, selectedWorkoutjest taka sama, jak ta używana w programie workouts. Inna instancja obiektu, nawet z tymi samymi właściwościami i wartościami, nie zostanie rozpoznana. Sprawdzana jest tylko tożsamość obiektu.

aktualizacja

Dodano obsługę kątową dla compareWith, która ułatwia ustawienie wartości domyślnej, gdy [ngValue]jest używana (dla wartości obiektów)

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

W ten sposób inna (nowa) instancja obiektu może zostać ustawiona jako wartość domyślna i compareFnjest używana do określenia, czy powinny być uważane za równe (na przykład, czy idwłaściwość jest taka sama.

Günter Zöchbauer
źródło
2
jeśli masz czas, czy mógłbyś się na to zdobyć? Z jakiegoś powodu, kiedy próbuję, $ event pojawia się jako zdarzenie, a nie obiekt. Jeśli zmienię zdarzenie na event.target.value, wartość pojawi się jako ciąg, taki jak „[obiekt]”
crh225
Wydaje mi się, że byłoby bardziej pomocne, gdybyś spróbował stworzyć Plunkera, który pozwoli odtworzyć twój problem ;-) Być może używasz [value]zamiast [ngValue]lub twój kod w jakiś sposób powoduje, że wartość zostanie przekonwertowana na ciąg.
Günter Zöchbauer
Co robisz c1i co c2wskazuje compareFn? A także, jak działa ocena w ciele funkcji?
DongBin Kim
Wartość selectedCountriesicountry
Günter Zöchbauer
1
Udało mi się to dzięki pierwszej części tej odpowiedzi.
The Sharp Ninja
35

po prostu ustaw wartość modelu na domyślną, jak chcesz:

selectedWorkout = 'back'

Stworzyłem tutaj widelec plnkr @Douglas , aby zademonstrować różne sposoby uzyskania pożądanego zachowania w angular2.

Matthijs
źródło
1
aby to działało dla mnie (w angular 4) musiałem również ustawić [ngValue] = "val". Moje itemssource nie było jednak tablicą obiektów, ale tylko tablicą ciągów. <select [(ngModel)]="selectedTimeFrame"> <option *ngFor="let val of timeFrames" [ngValue]="val">val</option> </select>
S. Robijns
33

Dodaj ten kod na pozycji o listy wyboru.

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

Mahesh
źródło
1
Jaki jest cel ustawienia [ngValue] na undefined?
bluePearl
1
To powinna być akceptowana odpowiedź. Ustawienie [ngValue] na niezdefiniowane prawidłowo obsługuje wybranie wartości domyślnej podczas pierwszego renderowania opcji „select”.
Max
Zgoda, to jest poprawna odpowiedź. Pozwala na użycie opcji na pozycji 0
mobiusinversion
@bluePearl model `` SelectedWorkout '' zaczyna się jako `` niezdefiniowany '', jeśli nic nie ustawisz. Wtedy musi to być wartość domyślna elementu.
Richard Aguirre
To najlepsza odpowiedź
Richard Aguirre
20

Możesz podejść w ten sposób:

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

lub w ten sposób:

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

lub możesz ustawić wartość domyślną w ten sposób:

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

lub

<option [value]="0">Please Select</option>
<option *ngFor="let workout of workouts" [value]="workout.name">{{workout.name}}</option>
Anil Samal
źródło
14

Użyj indeksu, aby wyświetlić pierwszą wartość jako domyślną

<option *ngFor="let workout of workouts; #i = index" [selected]="i == 0">{{workout.name}}</option>
Sajith Mantharath
źródło
5

Zgodnie z https://angular.io/api/forms/SelectControlValueAccessor potrzebujesz tylko:

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
źródło
4

Trochę walczyłem z tym, ale skończyło się na następującym rozwiązaniu ... może to komuś pomoże.

Szablon HTML:

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

Składnik:

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
źródło
3

W pełni rozwijam inne posty, oto co działa w przewodniku Szybki start Angular2,

Aby ustawić domyślny DOM: wraz z *ngFor, użyj warunkowej instrukcji w atrybucie <option>'s selected.

Aby ustawić wartość Controldomyślną: użyj jej argumentu konstruktora. W przeciwnym razie przed zmianą, gdy użytkownik ponownie wybierze opcję, która ustawia wartość formantu z atrybutem value wybranej opcji, wartość kontrolna będzie miała wartość null.

scenariusz:

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

narzut:

<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
źródło
3

Możesz użyć tego [ngModel]zamiast [(ngModel)]i jest OK

<select class="form-control" **[ngModel]="selectedWorkout"** (ngModelChange)="updateWorkout($event)">
   <option *ngFor="#workout of workouts">{{workout.name}}</option>
</select>
Saeed
źródło
3

Możesz zrobić jak wyżej:

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

W powyższym kodzie, jak widać, wybrany atrybut opcji powtarzania jest ustawiany na sprawdzenie indeksu powtarzającej się pętli listy. [attr. <nazwa atrybutu html>] służy do ustawiania atrybutu html w angular2.

Innym podejściem będzie ustawienie wartości modelu w pliku maszynopisu jako:

this.selectedWorkout = this.workouts.length > 0
                       ? this.workouts[0].name
                       : 'No data found';//'arm'
Pranav Labhe
źródło
1

Dodaj do odpowiedzi @Matthijs, upewnij się, że Twój selectelement ma nameatrybut i namejest unikalny w Twoim szablonie HTML. Angular 2 używa nazwy wejściowej do aktualizacji zmian. Dlatego jeśli istnieją zduplikowane nazwy lub nie ma nazwy dołączonej do elementu wejściowego, powiązanie zakończy się niepowodzeniem.

Wei Xu
źródło
0

Dodaj wybraną właściwość powiązania, ale upewnij się, że jest ona pusta, dla innych pól, np .:

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

Teraz to zadziała

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

Jeśli używasz formularza, namewewnątrz selecttagu powinno znajdować się pole .

Wszystko, co musisz zrobić, to po prostu dodać valuedo optiontagu.

selectedWorkout wartość powinna być „wstecz” i gotowe.

Vivek Doshi
źródło
0

Jeśli nie chcesz dwukierunkowego wiązania przez [(ngModel)], zrób to:

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

Właśnie przetestowałem mój projekt na Angular 4 i działa! AccountList to tablica obiektów Account, których nazwa jest właściwością Account.

Ciekawe spostrzeżenie:
[ngValue] = "acct" daje taki sam wynik jak [ngValue] = "acct.name".
Nie wiem, jak Angular 4 to robi!

Daniel C. Deng
źródło
0

Krok: 1 Utwórz właściwości zadeklaruj klasę

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

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

Pytanie: 2 Twoja klasa komponentów

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

Krok: 3 Wyświetl plik .html

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

Wynik:

wprowadź opis obrazu tutaj

Ram Pukar
źródło
0

Dla mnie definiuję kilka właściwości:

disabledFirstOption = true;

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

Następnie w konstruktorze i w ngOnInit

constructor() {
    this.disabledFirstOption = false;
}

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

I w szablonie dodaję to jako pierwszą opcję wewnątrz elementu select

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

Jeśli zezwolisz na wybranie pierwszej opcji, możesz po prostu usunąć użycie właściwości disabledFirstOption

Tinh Dang
źródło
0

W moim przypadku tutaj this.selectedtestSubmitResultViewjest ustawiona wartość domyślna na podstawie warunków, a zmienna testSubmitResultViewmusi być taka sama jak testSubmitResultView. To rzeczywiście zadziałało dla mnie

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

Po więcej informacji,

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ʜᴀɴᴛʜ ॐ
źródło
-1

Wcześniej miałem do czynienia z tym problemem i naprawiłem go na różne proste sposoby obejścia

Twój 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>

Następnie w swoim component.ts możesz wykryć wybraną opcję przez

gotit(name:string) {
//Use it from hare 
console.log(name);
}
Ramy hakam
źródło
-1

działa świetnie, jak widać poniżej:

<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>
André Rodrigues de Sousa
źródło
-1

Wystarczy umieścić ngModel i wartość, którą chcesz wybrać:

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>
q2design.net
źródło