Angular 2 Dropdown Options ค่าเริ่มต้น


115

ใน 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อะไร?

คำตอบ:


77

เพิ่มการเชื่อมโยงให้กับselectedคุณสมบัติเช่นนี้:

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

4
ดูเหมือนจะใช้งานไม่ได้ดูตัวเลือกที่ฉันเลือกมันไม่มีตัวบ่งชี้ที่เลือกไว้เลย
ClickThisNick

@ClickThisNick มันใช้งานได้เมื่อฉันทดสอบ ดูplnkrนี้ เมื่อโหลดเสร็จแล้วเมนูแบบเลื่อนลงที่เลือกจะแสดง "สอง" แม้ว่าค่าเริ่มต้นปกติจะเป็นองค์ประกอบแรก ("หนึ่ง")
Douglas

2
ความแตกต่างกับรหัสใน @Douglas plnr คือไม่มีการ[(ngModel)]ผูกดังนั้นจึงรับฟังการ[selected]ผูกใน plnkr และไม่อยู่ในรหัสของ OP (ดูคำตอบของฉันสำหรับลิงก์ไปยัง plnr ที่แยกออกมาซึ่งอธิบายถึงผลกระทบนี้)
Matthijs

2
การใช้รูปแบบไดนามิก: ใช้รูปแบบselected="workout.name == 'back'"ปฏิกิริยา:[selected]=workout.name == 'back'
fidev

@fidev คุณมีคำตอบที่ดีและมันคือสิ่งที่ฉันกำลังมองหา เพียงแค่ดูว่าตัวอย่างรูปแบบปฏิกิริยาของคุณไม่มีไฟล์". ฉันใช้รหัสของคุณกับตัวแปรอื่นเช่นนี้[selected]="workout.name == exercise.name"
Alfa Bravo

48

หากคุณกำหนดค่าเริ่มต้นให้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คุณสมบัติเหมือนกัน


2
ถ้าคุณมีเวลาคุณช่วยวางแผนสำหรับสิ่งนี้ได้ไหม ด้วยเหตุผลบางอย่างเมื่อฉันลองใช้ $ event จะพบว่าเป็นเหตุการณ์ไม่ใช่วัตถุ ถ้าฉันเปลี่ยนเหตุการณ์เป็น event.target.value ค่าจะอยู่ในรูปแบบสตริงเช่น "[object]"
crh225

ฉันเดาว่ามันจะมีประโยชน์มากกว่าถ้าคุณพยายามสร้าง Plunker ที่ช่วยให้เกิดปัญหาของคุณซ้ำ ;-) บางทีคุณอาจใช้[value]แทน[ngValue]หรือโค้ดของคุณทำให้ค่าถูกแปลงเป็นสตริง
GünterZöchbauer

ทำอะไรc1และc2บ่งบอกcompareFnอะไรใน? และการประเมินผลในส่วนของฟังก์ชันทำงานอย่างไร?
DongBin Kim

มูลค่าselectedCountriesและcountry
GünterZöchbauer

1
ฉันใช้งานได้จริงขอบคุณส่วนแรกของคำตอบนี้
The Sharp Ninja

35

เพียงตั้งค่าของโมเดลเป็นค่าเริ่มต้นที่คุณต้องการดังนี้:

selectedWorkout = 'back'

ฉันสร้างทางแยกของ @Douglas 'plnkr ที่นี่เพื่อสาธิตวิธีต่างๆในการรับพฤติกรรมที่ต้องการในเชิงมุม 2


1
เพื่อให้สิ่งนี้ได้ผลสำหรับฉัน (ในเชิงมุม 4) ฉันต้องตั้งค่า [ngValue] = "val" ด้วย itemssource ของฉันไม่ใช่อาร์เรย์ของออบเจ็กต์ แต่เป็นเพียงอาร์เรย์ของสตริง <select [(ngModel)]="selectedTimeFrame"> <option *ngFor="let val of timeFrames" [ngValue]="val">val</option> </select>
S. Robijns

33

เพิ่มรหัสนี้ที่ตำแหน่ง o ของรายการที่เลือก

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


1
จุดประสงค์ในการตั้งค่า [ngValue] เป็น undefined คืออะไร?
bluePearl

1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ การตั้งค่า [ngValue] เพื่อไม่ได้กำหนดไว้อย่างถูกต้องจัดการโดยมีการเลือกค่าเริ่มต้นเมื่อการแสดงผลครั้งแรก "select"
สูงสุด

ตกลงนี่เป็นคำตอบที่ถูกต้อง ให้คุณใช้ตัวเลือกที่ตำแหน่ง 0
mobiusinversion

@bluePearl โมเดล 'SelectedWorkout' เริ่มต้นเป็น 'ไม่ได้กำหนด' หากคุณไม่ได้ตั้งค่าอะไรเลยจากนั้นจะต้องเป็นค่า de ของรายการเริ่มต้น
Richard Aguirre

นี่คือคำตอบที่ดีที่สุด
Richard Aguirre

20

คุณสามารถเข้าใกล้วิธีนี้:

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


5

ตาม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;
}

4

ดิ้นรนเล็กน้อยกับสิ่งนี้ แต่ลงเอยด้วยวิธีแก้ปัญหาต่อไปนี้ ... อาจจะช่วยใครบางคนได้

เทมเพลต 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];
    }
}

3

พัฒนาโพสต์อื่น ๆ อย่างเต็มที่นี่คือสิ่งที่ใช้ได้ผลใน Angular2 อย่างรวดเร็ว

ในการตั้งค่าเริ่มต้น DOM: พร้อมกับ*ngForใช้คำสั่งเงื่อนไขในแอตทริบิวต์<option>'sselected

ในการตั้งค่าControlเริ่มต้น: ใช้อาร์กิวเมนต์ตัวสร้าง มิฉะนั้นก่อนการเปลี่ยนแปลงเมื่อผู้ใช้เลือกตัวเลือกอีกครั้งซึ่งตั้งค่าของตัวควบคุมด้วยแอตทริบิวต์ value ของตัวเลือกที่เลือกค่าควบคุมจะเป็นค่าว่าง

สคริปต์:

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

มาร์กอัป:

<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

คุณสามารถใช้[ngModel]แทน[(ngModel)]และใช้ได้

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

3

คุณสามารถทำได้ดังนี้:

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

ในโค้ดด้านบนอย่างที่คุณเห็นแอตทริบิวต์ที่เลือกของตัวเลือกการทำซ้ำถูกตั้งค่าในการตรวจสอบดัชนีของการวนซ้ำของรายการ [attr. <html attribute name>] ใช้สำหรับตั้งค่าแอตทริบิวต์ html ใน angular2

อีกวิธีหนึ่งคือการตั้งค่าโมเดลในไฟล์ typescript เป็น:

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

1

เพิ่มเติมในคำตอบของ @Matthijs โปรดตรวจสอบว่าselectองค์ประกอบของคุณมีnameแอตทริบิวต์และnameไม่ซ้ำกันในเทมเพลต html ของคุณ Angular 2 ใช้ชื่ออินพุตเพื่ออัปเดตการเปลี่ยนแปลง ดังนั้นหากมีชื่อที่ซ้ำกันหรือไม่มีชื่อติดอยู่กับองค์ประกอบอินพุตการเชื่อมโยงจะล้มเหลว


0

เพิ่มคุณสมบัติการผูกที่เลือกไว้ แต่อย่าลืมทำให้เป็นโมฆะสำหรับฟิลด์อื่น ๆ เช่น:

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

ตอนนี้มันจะทำงาน


0
<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 ค่าควรเป็น "ย้อนกลับ" และเสร็จสิ้น


0

หากคุณไม่ต้องการการเชื่อม 2 ทางผ่าน [(ngModel)] ให้ดำเนินการดังนี้:

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

เพิ่งทดสอบกับโครงการของฉันบน Angular 4 และใช้งานได้! accountsList คืออาร์เรย์ของอ็อบเจ็กต์ Account ที่ชื่อเป็นคุณสมบัติของ Account

ข้อสังเกตที่น่าสนใจ:
[ngValue] = "acct" ให้ผลลัพธ์เช่นเดียวกับ [ngValue] = "acct.name"
ไม่รู้ว่า Angular 4 สำเร็จได้อย่างไร!


0

ขั้นตอน: 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>

เอาท์พุท:

ใส่คำอธิบายภาพที่นี่


0

สำหรับฉันฉันกำหนดคุณสมบัติบางอย่าง:

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

และในเทมเพลตฉันเพิ่มสิ่งนี้เป็นตัวเลือกแรกภายในองค์ประกอบที่เลือก

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

หากคุณอนุญาตให้เลือกตัวเลือกแรกคุณก็สามารถลบการใช้คุณสมบัติ disabledFirstOption


0

ในกรณีของฉันที่นี่this.selectedtestSubmitResultViewมีการตั้งค่าที่มีค่าเริ่มต้นขึ้นอยู่กับเงื่อนไขและตัวแปรจะต้องเป็นหนึ่งเดียวกับtestSubmitResultView testSubmitResultViewสิ่งนี้ใช้ได้ผลกับฉันอย่างแท้จริง

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

สำหรับข้อมูลเพิ่มเติม,

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

ฉันประสบปัญหานี้มาก่อนและฉันได้แก้ไขด้วยวิธีแก้ปัญหาง่ายๆที่แตกต่างกัน

สำหรับ 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);
}

-1

ใช้งานได้ดีดังที่แสดงด้านล่าง:

<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

คุณเพียงแค่ใส่ ngModel และค่าที่คุณต้องการเลือก:

<select id="typeUser" ngModel="Advanced" name="typeUser">
  <option>Basic</option>
  <option>Advanced</option>
  <option>Pro</option>
</select>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.