ฉันจะตั้งค่าคุณสมบัติค่าใน AngularJS 'ng-options ได้อย่างไร


557

นี่คือสิ่งที่ดูเหมือนจะรบกวนผู้คนจำนวนมาก (รวมถึงฉัน)

เมื่อใช้ng-optionsคำสั่งใน AngularJS เพื่อกรอกตัวเลือกสำหรับ<select>แท็กฉันไม่สามารถหาวิธีตั้งค่าสำหรับตัวเลือกได้ เอกสารสำหรับเรื่องนี้ไม่ชัดเจนจริง ๆ - อย่างน้อยสำหรับคนธรรมดาอย่างฉัน

ฉันสามารถตั้งค่าข้อความสำหรับตัวเลือกได้อย่างง่ายดายเช่น:

ng-options="select p.text for p in resultOptions"

เมื่อresultOptionsเป็นเช่น:

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

ควรเป็นสิ่งที่ง่ายที่สุดในการตั้งค่าตัวเลือก แต่จนถึงตอนนี้ฉันก็ไม่เข้าใจ


12
มีปัญหาเดียวกันเพราะฉันไม่พบเอกสาร (ดังที่แสดงด้านล่าง) ชัดเจนมาก
benvds

1
การใช้ "select" ตามที่ปรากฎในคำถามนั้นผิดหลักเพราะ "select" ในบริบทนี้ไม่ใช่คำหลัก แต่เป็นตัวยึดตำแหน่งสำหรับนิพจน์ นี่คือจากเอกสารของ AngularJS: "select: ผลลัพธ์ของการแสดงออกนี้จะถูกผูกไว้กับรูปแบบขององค์ประกอบหลักหากไม่ได้ระบุการแสดงออกที่เลือกจะเริ่มต้นที่ค่า" ฉันให้รายละเอียดเพิ่มเติมในคำตอบด้านล่าง
Majix

สำหรับฉันนี่คือคำตอบที่ดีที่สุด stackoverflow.com/questions/12139152/…
Sanjay

1
หมายเหตุ: เพื่อให้ตัวเลือก ng ทำงานได้จำเป็นต้องใช้ ng-model !!!!!!!!! Ref: stackoverflow.com/a/13049740/234110
Anand Rockzz

คำตอบ:


698

ดูngOptions

ngOptions (เป็นทางเลือก) - { comprehension_expression=} - ในรูปแบบใดรูปแบบหนึ่งต่อไปนี้:

สำหรับแหล่งข้อมูลอาร์เรย์ : label for value in array select as label for value in array label group by group for value in array select as label group by group for value in array track by trackexpr สำหรับแหล่งข้อมูลวัตถุ: label for (key , value) in object select as label for (key , value) in object label group by group for (key, value) in object select as label group by group for (key, value) in object

ในกรณีของคุณมันควรจะเป็น

array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];

<select ng-options="obj.value as obj.text for obj in array"></select>

ปรับปรุง

ด้วยการอัปเดตเกี่ยวกับ AngularJS ตอนนี้มันเป็นไปได้ที่จะตั้งค่าจริงสำหรับvalueแอตทริบิวต์ของselectองค์ประกอบที่มีtrack byการแสดงออก

<select ng-options="obj.text for obj in array track by obj.value">
</select>

วิธีการจำสิ่งที่น่าเกลียดนี้

สำหรับทุกคนที่มีเวลาลำบากในการจำรูปแบบไวยากรณ์นี้: ฉันยอมรับว่านี่ไม่ใช่รูปแบบที่ง่ายที่สุดหรือสวยงามที่สุด ไวยากรณ์นี้เป็นชนิดของความเข้าใจในรายการ Python เวอร์ชันเพิ่มเติมและการรู้ที่ช่วยให้ฉันจดจำไวยากรณ์ได้ง่ายมาก มันเป็นแบบนี้:

รหัสหลาม:

my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]

# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']

นี่เป็นไวยากรณ์เดียวกันกับที่แสดงไว้ข้างต้น อย่างไรก็ตามใน<select>เรามักจะต้องแยกความแตกต่างระหว่างค่าจริงในรหัสและข้อความที่แสดง (ฉลาก) ใน<select>องค์ประกอบ

เช่นเดียวกับเราต้องการperson.idรหัส แต่เราไม่ต้องการแสดงidให้ผู้ใช้เห็น เราต้องการแสดงชื่อ ในทำนองเดียวกันเราไม่สนใจในperson.nameรหัส มีasคำหลักในการติดฉลากเนื้อหา ดังนั้นจึงเป็นเช่นนี้:

person.id as person.name for person in people

หรือแทนที่จะperson.idต้องการpersonอินสแตนซ์ / อ้างอิงเอง ดูด้านล่าง:

person as person.name for person in people

สำหรับวัตถุ JavaScript ก็ใช้วิธีเดียวกันเช่นกัน เพียงจำไว้ว่ารายการในวัตถุจะถูกแยกออก(key, value)เป็นคู่ ๆ


33
ตัวอย่างของคุณไม่ได้เติมคุณสมบัติของตัวเลือก มันกำหนดสิ่งที่จะถูกเก็บไว้ในรูปแบบขององค์ประกอบ <select> ดูความแตกต่างระหว่างobj.value เป็น obj.textและobj.text
Artem Andreev

57
แปลก แต่ฉันได้รับ <option value = "0"> 1st </option>, <option value = "1"> 2nd </option> ใน Chrome และ FF
Artem Andreev

49
ไม่ใช่ข้อผิดพลาดมันเป็นคุณสมบัติ angularjs จัดการ ngOptions และ ngModel ภายในด้วยวิธีนี้ช่วยให้คุณสามารถใช้วัตถุชนิดใดก็ได้เป็นค่าในตัวเลือกแทนที่จะเป็นสตริงเท่านั้น คุณไม่ควรพยายามที่จะรับค่าของตัวเลือกแบบอื่น ๆ ที่อยู่รอบตัวคุณเพียงแค่ใช้ ngModel ที่คุณแนบมาเพื่อเลือกองค์ประกอบ
อายุKontacı

4
ฉันขอแตกต่าง ภายใน directive ที่เลือกสามารถใช้โมเดลที่มองไม่เห็นของตัวเองเพื่อติดตามตัวเลือกที่เลือกไว้ได้อย่างง่ายดาย แม้ว่ามันจะไม่ได้ติดตามค่าของรูปแบบภายในอย่างน้อยก็สามารถแสดงผลตัวเลือกและเพียงแค่เสริมและเลือกตัวเลือกที่ว่างเปล่า (ซึ่งเป็นพฤติกรรมที่มันทำตอนนี้ถ้าคุณตั้งค่ารูปแบบเป็นค่าที่ไม่ได้อยู่ในชุดตัวเลือก) . การอ้างอิงเพียงอย่างเดียวสำหรับการแสดงตัวเลือกคือตัวเลือก - หลักการของ POLA มีผลบังคับใช้ที่นี่
Ezekiel Victor

3
ทำไมคำตอบนี้จึงมีคะแนนโหวตจำนวนมากเมื่อไม่ได้ให้คำตอบ? คำตอบของ frm.adiputra ถูกต้อง
Noishe

136

วิธีที่ค่าของคุณลักษณะรับค่าของมัน:

  • เมื่อใช้อาเรย์เป็นแหล่งข้อมูลมันจะเป็นดัชนีขององค์ประกอบอาเรย์ในการทำซ้ำแต่ละครั้ง
  • เมื่อใช้วัตถุเป็นแหล่งข้อมูลวัตถุนั้นจะเป็นชื่อคุณสมบัติในการวนซ้ำแต่ละครั้ง

ดังนั้นในกรณีของคุณมันควรจะเป็น:

obj = { '1': '1st', '2': '2nd' };

<select ng-options="k as v for (k,v) in obj"></select>

15
+1 สำหรับการอธิบายว่า Angular ตั้งค่าคุณลักษณะขององค์ประกอบตัวเลือกอย่างไร
Mark Rajcok

1
สิ่งนี้ไม่ได้ตั้งค่า ค่าเริ่มต้นเป็นตัวเลข แต่คุณไม่สามารถระบุ "ค่า" จริง ๆ ได้ .. ซ้ำซ้อน ..
เดินทาง

13
@Trip ถ้าคุณ 'ตรวจสอบ' ตัวเลือกที่เลือกคุณจะเห็นตัวเลข แต่ถ้าคุณดูค่าที่ถูกผูกไว้ในแบบจำลองค่าในกรณีนี้คือค่า 'k' มันสับสน blesh มีเสียงอึกทึกที่แสดงสิ่งนี้ในคำตอบนี้: stackoverflow.com/questions/13047923/… plnkr.co/edit/vJOljg?p=preview
TsenYing

4
สิ่งนี้ควรรวมอยู่ในเอกสารเชิงมุมสั้นและแม่นยำ +1
devric

2
นี่เป็นทางออกเดียวที่ได้ผลสำหรับฉัน ปวดหัวอะไรที่น่ารังเกียจ
Jon

121

ฉันมีปัญหานี้เช่นกัน ฉันไม่สามารถกำหนดค่าของฉันในตัวเลือก ng ทุกตัวเลือกที่สร้างขึ้นถูกตั้งค่าเป็น 0, 1, ... , n

เพื่อให้ถูกต้องฉันได้ทำสิ่งนี้ในตัวเลือกของฉัน:

HTML:

<select ng-options="room.name for room in Rooms track by room.price">
    <option value="">--Rooms--</option>
</select>

ผมใช้ "ติดตามด้วย" room.priceการตั้งค่าของฉันทั้งหมดที่มี

(ตัวอย่างนี้ดูด: เพราะหากมีราคามากกว่าหนึ่งราคารหัสจะล้มเหลวดังนั้นโปรดแน่ใจว่ามีค่าแตกต่างกัน)

JSON:

$scope.Rooms = [
            { name: 'SALA01', price: 100 },
            { name: 'SALA02', price: 200 },
            { name: 'SALA03', price: 300 }
        ];

ผมได้เรียนรู้ได้จากบล็อกโพสต์วิธีการตั้งค่าเริ่มต้นของการเลือกองค์ประกอบที่เลือกใช้ Angular.JS NG-ตัวเลือกและการติดตามโดย

ดูวิดีโอ. มันเป็นคลาสที่ดี :)


8
มันทำงานได้อย่างสมบูรณ์แบบ ที่ด้านบนของมันจะช่วยให้การใช้องค์ประกอบดาต้าลิสต์ที่มี <select> ที่มีอยู่เพื่อให้ดาต้าลิสต์สามารถอ้างอิงตัวเลือกผ่านทางค่าของพวกเขา ขอขอบคุณ @Bruno Gomes
climboid

3
นี่เป็นทางออกเดียวที่เหมาะกับฉัน ขอบคุณ
Niner

9
นี่คือคำตอบที่เหมาะสมที่สุดสำหรับตัวเลือก ng พร้อมค่าของกล่องตัวเลือกเพื่อให้ตรงกับอาร์เรย์ / วัตถุ ฉันจะให้10,000 คะแนนสำหรับคุณในการบันทึกวันของทุกคนถ้ามีระบบการแลกเปลี่ยนรางวัล ไวยากรณ์ที่แปลกประหลาดที่สุดจากทีมเชิงมุม
webblover

2
ขอบคุณ! มันช่างน่าหงุดหงิดมานานแล้ว!
Sean Thompson

2
ฉันหวังว่าราคาห้องพักจะไม่เหมือนเดิมเพราะเมื่อถึงเวลาพัก
nilskp

47

หากคุณต้องการเปลี่ยนค่าoptionองค์ประกอบของคุณเพราะในที่สุดจะส่งแบบฟอร์มไปยังเซิร์ฟเวอร์แทนที่จะทำสิ่งนี้

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

คุณสามารถทำได้:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

ค่าที่คาดหวังจะถูกส่งผ่านแบบฟอร์มภายใต้ชื่อที่ถูกต้อง


2
ฉันจะเพิ่มที่มากกว่าการใช้งาน<input type="hidden" name="text" value="{{ text }}" />, ng-valueฉันต้องการใช้ ดังนั้น: <input type="hidden" name="text" ng-value="{{ text }}" />.
Dan Atkinson

เพื่อชี้แจงในกรณีของฉันฉันไม่ได้ส่งแบบฟอร์มผ่าน Angular โดยใช้โพสต์ json - แต่ฉันส่งแบบปกติโดยใช้โพสต์ http ดังนั้นการแทนที่ค่าที่ Angular ใส่ไว้ในแท็ก <options> ทำให้ฉันสามารถส่งสิ่งที่ถูกต้องได้ ค่า (ขอบคุณ!) ฉันไม่จำเป็นต้องใช้ ng-value ในอินพุตที่ซ่อนอยู่ แต่ฉันต้องการตั้งค่าแท็กค่าเป็นบันทึกย่อการโพสต์ดั้งเดิม
FireDragon

26

ในการส่งค่าที่กำหนดเองที่เรียกว่าmy_heroไปยังเซิร์ฟเวอร์โดยใช้แบบฟอร์มปกติส่ง:

JSON:

"heroes": [
  {"id":"iron", "label":"Iron Man Rocks!"},
  {"id":"super", "label":"Superman Rocks!"}
]

HTML:

<select ng-model="hero" ng-options="obj.id as obj.label for obj in heroes"></select>
<input type="hidden" name="my_hero" value="{{hero}}" />

เซิร์ฟเวอร์จะได้รับอย่างใดอย่างหนึ่งironหรือเป็นค่าของsupermy_hero

นี่คล้ายกับคำตอบโดย @neemzyแต่การระบุข้อมูลแยกต่างหากสำหรับvalueแอตทริบิวต์


24

ดูเหมือนว่าng-optionsจะมีความซับซ้อน (อาจทำลาย) ที่จะใช้ แต่ในความเป็นจริงเรามีปัญหาสถาปัตยกรรม

AngularJS ทำหน้าที่เป็นกรอบ MVC สำหรับแอปพลิเคชัน HTML + JavaScript แบบไดนามิก ในขณะที่องค์ประกอบ (V) iew ให้ HTML "templating" จุดประสงค์หลักของมันคือการเชื่อมต่อการกระทำของผู้ใช้ผ่านตัวควบคุมเพื่อการเปลี่ยนแปลงในรูปแบบ ดังนั้นในระดับที่เหมาะสมของนามธรรมจากการที่ไปทำงานใน AngularJS นั่นคือองค์ประกอบเลือกกำหนดค่าในรูปแบบให้เป็นค่าจากแบบสอบถาม

  • วิธีการนำเสนอแถวแบบสอบถามให้ผู้ใช้เห็นถึงความกังวลของ (V) iew และng-optionsให้forคำหลักเพื่อกำหนดว่าเนื้อหาขององค์ประกอบตัวเลือกควรเป็นเช่น p.text for p in resultOptionsไร
  • วิธีการนำเสนอแถวที่เลือกไปยังเซิร์ฟเวอร์เป็นเรื่องที่กังวล (M) odel ดังนั้นจึงng-optionsมีคำหลักเพื่อระบุสิ่งที่มีค่ามีให้กับรูปแบบเช่นเดียวกับในask as v for (k,v) in objects

วิธีแก้ปัญหาที่ถูกต้องคือปัญหานี้เป็นสถาปัตยกรรมในธรรมชาติและเกี่ยวข้องกับการปรับเปลี่ยน HTML ของคุณเพื่อให้ odel (M) ทำการสื่อสารเซิร์ฟเวอร์เมื่อจำเป็น (แทนที่จะเป็นผู้ใช้ที่ส่งแบบฟอร์ม)

หากหน้า MVC HTML นั้นไม่จำเป็นต้องใช้วิศวกรรมมากเกินไปสำหรับปัญหาที่เกิดขึ้น: ให้ใช้เฉพาะส่วนการสร้าง HTML ของส่วนประกอบ AngularJS (V) iew ในกรณีนี้ให้ทำตามรูปแบบเดียวกันที่ใช้สำหรับสร้างองค์ประกอบเช่น&lt;li /&gt;'s ภายใต้&lt;ul /&gt;' และวาง ng-repeat บนองค์ประกอบตัวเลือก:

<select name=“value”>
    <option ng-repeat=“value in Model.Values value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

ในฐานะkludgeเราสามารถย้ายแอตทริบิวต์ชื่อขององค์ประกอบที่เลือกไปยังองค์ประกอบอินพุตที่ซ่อนอยู่ได้เสมอ:

<select ng-model=“selectedValue ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden name=“value value=“{{selectedValue}}” />

ประสิทธิภาพไม่ดีเมื่อใช้ ng-repeat กับองค์ประกอบตัวเลือก คุณควรใช้ ng-options บนตัวเลือกเอง
DrCord

@DrCord: การใช้ ng-repeat ในองค์ประกอบตัวเลือกจะถูกนำเสนอเป็นวิธีการแก้ปัญหาเฉพาะในกรณีที่แยก (เมื่อหน้า MVC HTML ที่เหมาะสมไม่จำเป็นต้องวิศวกรรมมากเกินไป) บางทีผู้ลงคะแนนไม่พร้อมอย่างมาก มันจะได้รับการแก้ไขให้โทรออกโดยเฉพาะอย่างยิ่งที่ ng-repeat ในองค์ประกอบตัวเลือกไม่ได้เป็นกรณีที่เหมาะ
Joshcodes

1
ในฐานะที่เป็น Angular N00b ฉันจะเลือกวิธีการแก้ปัญหานี้เพราะในครั้งแรกดูเหมือนว่าคำแนะนำที่เป็นธรรมและมีแนวโน้มที่จะทำงาน ไวยากรณ์ที่แนะนำในคำตอบอื่น ๆ คือการพูดอย่างน้อยแปลกประหลาด - แม้ว่าหนึ่งในตัวเลือกมากมายที่เกิดขึ้นกับการทำงาน มันเป็นทางออกที่ถูกกฎหมายและถ้ามันหลีกเลี่ยงการเพิ่มประสิทธิภาพก่อนวัยอันควรมันก็ใช้ได้ การลงคะแนนเสียงเป็นเพียงความหมาย
Ian Lewis

2
นี่คือสิ่งที่กล่าวในเว็บไซต์ AngularJS: docs.angularjs.org/api/ng/directive/select "Note: ngOptions provides an iterator facility for the <option> element which should be used instead of ngRepeat when you want the select model to be bound to a non-string value. This is because an option element can only be bound to string values at present.". ไม่มีการเอ่ยถึงประสิทธิภาพ แต่เพียงว่า ngOptions เป็นทางเลือกแทน ngRepeat
Ian Lewis

@IanLewis ขอบคุณที่มีเหตุผล ฉันไม่เข้าใจว่าทำไม ngRepeat จึงมีประสิทธิภาพน้อยกว่าตัวเลือกของตัวเลือก unbound มากกว่าที่อยู่บนแท็ก <li>
Joshcodes

20

คุณสามารถทำได้:

<select ng-model="model">
    <option value="">Select</option>
    <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>

- อัพเดท

หลังจากการปรับปรุงบางผู้ใช้frm.adiputra 's วิธีการแก้ปัญหาจะดีกว่ามาก รหัส:

obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>

8
เป็นการดีกว่าที่จะใช้ตัวเลือก ng ภายในองค์ประกอบ / คำสั่งที่เลือก เช่น <select ng-model = "model" ng-options = "obj.id เป็น obj.name สำหรับ obj ใน array"> สิ่งที่คุณมี แต่มันจะไม่ทำงานกับโครงสร้างเชิงมุมอื่น ๆ ตัวอย่างเช่น ng-click นี้จะไม่ทำงานกับรหัสของคุณ: <a ng-click="model=1"> เลือก 1 </a> แต่จะใช้งานได้หากใช้ ng-options
Mark Rajcok

ฉันเพิ่งพบข้อผิดพลาดแปลก ๆ เพราะทำอย่างนี้ การค้นหาที่เจ็บปวดจำนวนมากนำฉันไปสู่การค้นพบตัวเลือก ng และข้อผิดพลาดก็หายไป ดูเหมือนว่า ng-model ต้องการให้แอตทริบิวต์ value ของตัวเลือกนั้นเป็นตัวเลขและเพิ่มขึ้นจาก 0 หากคุณเปลี่ยนค่าเป็นดัชนีที่ไม่ใช่ตัวเลขโดยใช้แท็ก ng-repeat และ <option> การเปลี่ยนแปลงในตัวแบบจะไม่เสมอไป สะท้อนในกล่องเลือก
Noishe

14

ฉันได้ต่อสู้กับปัญหานี้มาระยะหนึ่งแล้ว ฉันอ่านเอกสารของ AngularJS บทความนี้และโพสต์อื่น ๆ รวมถึงบล็อกบางส่วนที่นำไปสู่ พวกเขาทั้งหมดช่วยให้ฉันคร่ำครวญรายละเอียดปลีกย่อย แต่ท้ายที่สุดดูเหมือนว่าจะเป็นหัวข้อที่สับสน ng-optionsส่วนใหญ่เป็นเพราะความแตกต่างกับการสร้างประโยคหลาย

ในท้ายที่สุดสำหรับฉันมันลงมาน้อยมาก

กำหนดขอบเขตที่กำหนดดังนี้:

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

นี่คือทั้งหมดที่ฉันต้องการเพื่อให้ได้ผลลัพธ์ที่ต้องการ:

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

track byแจ้งให้ทราบผมไม่ได้ใช้ การใช้track byรายการที่เลือกจะส่งคืนวัตถุที่ตรงกับ FirmnessID เสมอแทนที่จะเป็น FirmnessID เอง ตอนนี้ตรงกับเกณฑ์ของฉันซึ่งก็คือมันควรจะส่งคืนค่าตัวเลขมากกว่าวัตถุและเพื่อใช้ng-optionsในการปรับปรุงประสิทธิภาพที่ได้รับจากการไม่สร้างขอบเขตใหม่สำหรับแต่ละตัวเลือกที่สร้างขึ้น

นอกจากนี้ผมจำเป็นแถวแรกว่างเปล่าดังนั้นฉันก็เพิ่ม<option>ไปยัง<select>องค์ประกอบ

นี่คือPlunkrที่แสดงงานของฉัน


ตำนาน. นี่คือสิ่งที่ฉันต้องการ Thankyou
Kildareflare

เยี่ยมมาก แต่จุดประสงค์ของคีย์ "ค่า" คืออะไร พวกเขาดูเหมือนจะไม่จำเป็น
mhenry1384

ไม่เกี่ยวข้องกับตัวอย่าง พวกเขาเป็นเพียงส่วนหนึ่งของข้อมูลดั้งเดิมที่ลูกค้าของฉันให้ไว้
Jeffrey A. Gochin

11

แทนที่จะใช้คุณลักษณะ 'ติดตามโดย' ใหม่คุณสามารถทำได้ด้วยอาร์เรย์หากคุณต้องการให้ค่าเหมือนกันกับข้อความ:

<select ng-options="v as v for (k,v) in Array/Obj"></select>

สังเกตความแตกต่างระหว่างไวยากรณ์มาตรฐานซึ่งจะทำให้ค่าคีย์ของ Object / Array และดังนั้น 0,1,2 เป็นต้นสำหรับอาร์เรย์:

<select ng-options"k as v for (k,v) in Array/Obj"></select>

k เป็นโวลต์กลายเป็นโวลต์เป็นวี

ฉันค้นพบว่าสิ่งนี้ขึ้นอยู่กับสามัญสำนึกที่ดูที่ไวยากรณ์ (k, v) เป็นข้อความจริงที่แยกอาร์เรย์ / วัตถุออกเป็นคู่ของค่าคีย์

ในคำสั่ง 'k as v' k จะเป็นค่าและ v จะเป็นตัวเลือกข้อความที่แสดงต่อผู้ใช้ ฉันคิดว่า 'track by' นั้นยุ่งและเกินกำลัง


Waaaaat? ใช้งานได้กับอาร์เรย์ทั่วสถานที่ในหน้าของฉันเราใช้ AngularJS รุ่นเดียวกันหรือไม่
KthProg

11

นี่เหมาะที่สุดสำหรับทุกสถานการณ์ตามฉัน:

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

ที่ซึ่งคุณสามารถใช้โมเดลของคุณเพื่อผูกข้อมูล คุณจะได้รับค่าตามที่วัตถุจะมีและการเลือกเริ่มต้นตามสถานการณ์ของคุณ


รักทางออกนี้ ผู้ช่วยเชิงมุมสำหรับคำสั่งนี้มีความซับซ้อนเกินความจำเป็น ขอบคุณที่เป็นผู้ตัดสินการใช้งาน
David Melin

9

นี่คือวิธีที่ฉันจะแก้ไขปัญหานี้ ฉันติดตามการเลือกตามค่าและตั้งค่าคุณสมบัติรายการที่เลือกเป็นแบบจำลองในรหัส JavaScript ของฉัน

Countries =
[
    {
        CountryId = 1, Code = 'USA', CountryName = 'United States of America'
    },
    {
       CountryId = 2, Code = 'CAN', CountryName = 'Canada'
    }
]
<select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId">

vm{CountryId =1, Code = 'USA', CountryName='United States of America'}เป็นตัวควบคุมและประเทศในการควบคุมของฉันที่ดึงมาจากบริการที่

เมื่อฉันเลือกประเทศอื่นจากรายการแบบเลื่อนลงที่เลือกและโพสต์หน้าของฉันด้วย "บันทึก" ฉันมีประเทศที่ถูกต้อง


8

ng-optionsสั่งไม่ได้กำหนดแอตทริบิวต์ค่าใน<options>องค์ประกอบอาร์เรย์:

ใช้limit.value as limit.text for limit in limitsวิธีการ:

ตั้งค่า<option>ป้ายกำกับของเป็นlimit.text
บันทึกlimit.valueค่าลงในตัวเลือกng-model

ดูกองมากเกินคำถามAngularJS NG-ตัวเลือกการแสดงผลไม่ถูกค่า



4

คุณสามารถใช้ ng-options เพื่อให้เกิดการเลือกแท็กที่สัมพันธ์กับค่าและสมาชิกที่แสดง

ในขณะที่ใช้แหล่งข้อมูลนี้

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

คุณสามารถใช้ด้านล่างเพื่อผูกแท็กที่คุณเลือกตามมูลค่าและชื่อ

<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>

มันใช้งานได้ดี


1
โปรดเพิ่มคำตอบเฉพาะรหัสของคุณพร้อมคำอธิบายเพื่อหลีกเลี่ยงความเข้าใจผิดที่ StackOverflow เป็นบริการเขียนโค้ดฟรี
Yunnosch

3

ผู้ใช้frm.adiputraคำตอบที่ถูกต้องสำหรับคำถามนี้ดูเหมือนจะเป็นวิธีเดียวที่จะควบคุมแอตทริบิวต์ค่าขององค์ประกอบตัวเลือกอย่างชัดเจน

อย่างไรก็ตามฉันเพียงต้องการเน้นว่า "เลือก" ไม่ใช่คำหลักในบริบทนี้ แต่เป็นเพียงตัวยึดตำแหน่งสำหรับนิพจน์ โปรดอ้างอิงรายการต่อไปนี้สำหรับคำจำกัดความของการแสดงออก "เลือก" เช่นเดียวกับการแสดงออกอื่น ๆ ที่สามารถใช้ในคำสั่ง ng- ตัวเลือก

การใช้ select ตามที่ปรากฎในคำถาม:

ng-options='select p.text for p  in resultOptions'

เป็นหลักผิด

จากรายการของนิพจน์ดูเหมือนว่าtrackexprอาจถูกใช้เพื่อระบุค่าเมื่อมีการให้ตัวเลือกในอาร์เรย์ของวัตถุ แต่ถูกใช้กับการจัดกลุ่มเท่านั้น


จากเอกสารของ AngularJS สำหรับตัวเลือก ng:

  • array / object : นิพจน์ที่ประเมินเป็นอาร์เรย์ / วัตถุเพื่อวนซ้ำ
  • value : ตัวแปรท้องถิ่นซึ่งจะอ้างอิงถึงแต่ละรายการในอาร์เรย์หรือแต่ละค่าคุณสมบัติของวัตถุในระหว่างการทำซ้ำ
  • สำคัญ : ตัวแปรท้องถิ่นซึ่งจะอ้างถึงชื่อทรัพย์สินในวัตถุในช่วงการทำซ้ำ
  • label : ผลลัพธ์ของการแสดงออกนี้จะเป็นป้ายกำกับสำหรับองค์ประกอบ นิพจน์ส่วนใหญ่จะอ้างถึงตัวแปรค่า (เช่น value.propertyName)
  • select : ผลลัพธ์ของการแสดงออกนี้จะถูกผูกไว้กับรูปแบบขององค์ประกอบหลัก หากไม่ได้ระบุไว้นิพจน์เลือกจะใช้ค่าเริ่มต้นเป็นค่า
  • กลุ่ม : ผลลัพธ์ของนิพจน์นี้จะใช้ในการจัดกลุ่มตัวเลือกโดยใช้องค์ประกอบ DOM
  • trackexpr : ใช้เมื่อทำงานกับอาร์เรย์ของวัตถุ ผลลัพธ์ของนิพจน์นี้จะถูกใช้เพื่อระบุวัตถุในอาร์เรย์ trackexpr มักจะอ้างถึงตัวแปรค่า (เช่น value.propertyName)

3

การเลือกไอเท็มใน ng-options อาจเป็นเรื่องยากขึ้นอยู่กับวิธีที่คุณตั้งค่าแหล่งข้อมูล

หลังจากที่ต้องดิ้นรนกับพวกเขามาระยะหนึ่งผมก็ลงเอยด้วยการทำตัวอย่างกับแหล่งข้อมูลทั่วไปที่ผมใช้ คุณสามารถค้นหาได้ที่นี่:

http://plnkr.co/edit/fGq2PM?p=preview

ตอนนี้เพื่อให้ ng-options ทำงานต่อไปนี้เป็นสิ่งที่ควรพิจารณา:

  1. โดยปกติคุณจะได้รับตัวเลือกจากแหล่งหนึ่งและค่าที่เลือกจากแหล่งอื่น ตัวอย่างเช่น:
    • สถานะ :: data สำหรับ ng-options
    • user.state :: ตัวเลือกเพื่อตั้งค่าตามที่เลือก
  2. ขึ้นอยู่กับ 1 สิ่งที่ง่ายที่สุด / ตรรกะที่ต้องทำคือการเติมตัวเลือกที่มีแหล่งที่มาหนึ่งและจากนั้นตั้งค่ารหัสรางที่เลือก มันจะดีกว่าถ้าได้รับชุดข้อมูลแบบผสม
  3. AngularJS key | labelช่วยให้การควบคุมเพื่อเลือกถือมากกว่า ตัวอย่างออนไลน์จำนวนมากวางวัตถุเป็น 'คีย์' และหากคุณต้องการข้อมูลจากวัตถุที่กำหนดให้เป็นเช่นนั้นมิฉะนั้นใช้คุณสมบัติเฉพาะที่คุณต้องการเป็นคีย์ (ID, CODE, ฯลฯ .. เช่นเดียวกับในตัวอย่าง plckr)
  4. วิธีการตั้งค่าของการควบคุมแบบหล่นลง / เลือกขึ้นอยู่กับ # 3

    • หากคีย์ดรอปดาวน์เป็นคุณสมบัติเดียว (เช่นในตัวอย่างทั้งหมดใน plunkr) คุณเพิ่งตั้งค่าเช่น: $scope.dropdownmodel = $scope.user.state;
    • หากคุณตั้งค่าวัตถุเป็นคีย์คุณจะต้องวนลูปตัวเลือกแม้การกำหนดวัตถุจะไม่ตั้งค่ารายการตามที่เลือกเนื่องจากจะมีแฮชคีย์ที่แตกต่างกันเช่น:

      for (var i = 0, len = $scope.options.length; i < len; i++) {
        if ($scope.options[i].id == savedValue) { // Your own property here:
          console.log('Found target! ');
          $scope.value = $scope.options[i];
          break;
        }
      }

คุณสามารถแทนที่ savedValue $scope.myObject.myPropertyสำหรับสถานที่เดียวกันในวัตถุอื่น


ในอีกหนึ่งปีต่อมาฉันขอขอบคุณตัวอย่างพลั่ว มีประโยชน์มาก.
bob.mazzo

3

สำหรับฉันคำตอบโดย Bruno Gomesเป็นคำตอบที่ดีที่สุด

แต่จริงๆแล้วคุณไม่จำเป็นต้องกังวลเกี่ยวกับการตั้งค่าคุณสมบัติของตัวเลือกที่เลือก AngularJS จะดูแลเรื่องนี้ ให้ฉันอธิบายอย่างละเอียด

โปรดพิจารณาซอนี้

angular.module('mySettings', []).controller('appSettingsCtrl', function ($scope) {

    $scope.timeFormatTemplates = [{
        label: "Seconds",
        value: 'ss'
    }, {
        label: "Minutes",
        value: 'mm'
    }, {
        label: "Hours",
        value: 'hh'
    }];


    $scope.inactivity_settings = {
        status: false,
        inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.activity_settings = {
        status: false,
        active_time: 60 * 5 * 3, // 15 min (default value), that is,  900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.changedTimeFormat = function (time_format) {
        'use strict';

        console.log('time changed');
        console.log(time_format);
        var newValue = time_format.value;

        // do your update settings stuffs
    }
});

ตามที่คุณเห็นในผลลัพธ์ซอ, สิ่งที่คุณเลือกสำหรับตัวเลือกกล่องเป็นค่าที่กำหนดเองของคุณ, หรือค่าอัตโนมัติที่สร้างขึ้นโดย 0, 1, 2 โดย AngularJS, มันไม่สำคัญในเอาต์พุตของคุณเว้นแต่ว่าคุณกำลังใช้ jQuery หรือ ไลบรารีอื่น ๆ เพื่อเข้าถึงค่าของตัวเลือกกล่องคำสั่งผสมที่เลือกและจัดการตามนั้น


3

หนึ่งปีหลังจากคำถามฉันต้องหาคำตอบสำหรับคำถามนี้เพราะไม่ใช่สิ่งเหล่านี้ให้คำตอบจริงอย่างน้อยฉัน

คุณได้ถามถึงวิธีการเลือกตัวเลือก แต่ไม่มีใครบอกว่าทั้งสองสิ่งนี้ไม่เหมือนกัน:

หากเรามีตัวเลือกดังนี้:

$scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

และเราพยายามตั้งค่าตัวเลือกเริ่มต้นดังนี้:

$scope.incorrectlySelected = { label: 'two', value: 2 };

มันจะไม่ทำงาน แต่ถ้าคุณพยายามเลือกตัวเลือกเช่นนี้:

$scope.correctlySelected = $scope.options[1];

มันจะทำงาน

แม้ว่าทั้งสองวัตถุที่มีคุณสมบัติเดียวกัน AngularJS จะพิจารณาพวกเขาเป็นแตกต่างกันเพราะ AngularJS เปรียบเทียบโดยการอ้างอิง

ลองดูที่ซอที่http://jsfiddle.net/qWzTb/


3

โปรดใช้แทร็กตามคุณสมบัติที่แยกค่าและป้ายกำกับในกล่องที่เลือก

โปรดลอง

<select ng-options="obj.text for obj in array track by obj.value"></select>

ซึ่งจะกำหนดป้ายกำกับที่มีข้อความและค่าที่มีค่า (จากอาร์เรย์)



2

มันเป็นความเจ็บปวดเสมอสำหรับนักพัฒนาที่จะมีตัวเลือก ng ตัวอย่างเช่น: การรับค่าที่เลือกว่าง / ว่างในแท็กเลือก โดยเฉพาะอย่างยิ่งเมื่อจัดการกับวัตถุ JSON ในตัวเลือก ng มันจะน่าเบื่อมากขึ้น ที่นี่ฉันได้ทำแบบฝึกหัดเกี่ยวกับเรื่องนั้น

วัตถุประสงค์: ทำซ้ำอาร์เรย์ของวัตถุ JSON ผ่าน ng-option และตั้งค่าองค์ประกอบแรกที่เลือก

ข้อมูล:

someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]

ในแท็กที่เลือกฉันต้องแสดง xyz และ abc โดยที่ xyz ต้องเลือกโดยไม่ต้องใช้ความพยายามมาก

HTML:

<pre class="default prettyprint prettyprinted" style=""><code>
    &lt;select class="form-control" name="test" style="width:160px"    ng-options="name.someName for name in someNames" ng-model="testModel.test" ng-selected = "testModel.test = testModel.test || someNames[0]"&gt;
&lt;/select&gt;
</code></pre>

จากตัวอย่างโค้ดข้างต้นคุณอาจหลุดพ้นจากการพูดเกินจริงนี้

การอ้างอิงอื่น:



1
<select ng-model="output">
   <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
</select>

1
ngOptions ให้ประโยชน์บางอย่างเช่นการลดหน่วยความจำและการเพิ่มความเร็วโดยไม่สร้างขอบเขตใหม่สำหรับแต่ละอินสแตนซ์ซ้ำ ๆ ดูที่: docs.angularjs.org/api/ng/directive/ngOptions
mggSoft

1

เรียกใช้ข้อมูลโค้ดและดูการเปลี่ยนแปลง นี่คือหมายเหตุสำหรับความเข้าใจอย่างรวดเร็ว

  1. ตัวอย่างที่ 1 ng-option="os.name for os in osList track by os.id"(การเลือก นี่track by os.idเป็นสิ่งที่สำคัญและควรจะมีและos.id as ไม่ควรos.nameมีก่อน

    • ng-model="my_os"ควรตั้งค่าไปยังวัตถุที่มีคีย์เป็นรหัสmy_os={id: 2}เช่น
  2. ตัวอย่างที่ 2 (การเลือก ng-option="os.id as os.name for os in osList"Value): ที่นี่track by os.id ไม่ควรจะมีและos.id as ควรจะos.nameมีมาก่อน

    • ng-model="my_os"ควรตั้งค่าเช่นmy_os= 2

ข้อมูลโค้ดที่เหลือจะอธิบาย


0

อย่างที่หลายคนพูดไว้ก่อนหน้านี้ถ้าฉันมีข้อมูลบางอย่างเช่นนี้:

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

ฉันจะใช้มันเหมือน:

<select
    ng-model="selectedCountry"
    ng-options="obj.name for obj  in countries">
</select>

ในตัวควบคุมของคุณคุณต้องตั้งค่าเริ่มต้นเพื่อกำจัดรายการที่ว่างเปล่าแรก:

 $scope.selectedCountry = $scope.countries[0];

 // You need to watch changes to get selected value
 $scope.$watchCollection(function() {
   return $scope.selectedCountry
 }, function(newVal, oldVal) {
     if (newVal === oldVal) {
       console.log("nothing has changed " + $scope.selectedCountry)
     } 
     else {
       console.log('new value ' + $scope.selectedCountry)
     }
 }, true)

0

นี่คือวิธีที่ฉันแก้ปัญหานี้ในแอปพลิเคชันรุ่นเก่า:

ใน HTML:

ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"

ใน JavaScript:

vm.kitTypes = [
    {"id": "1", "name": "Virtual"},
    {"id": "2", "name": "Physical"},
    {"id": "3", "name": "Hybrid"}
];

...

vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
    return value.id === (vm.itemTypeId || 1);
})[0];

HTML ของฉันแสดงค่าตัวเลือกอย่างถูกต้อง


0

คำสั่ง ngOptions:

$scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}];
  • Case-1) เลเบลสำหรับค่าในอาร์เรย์:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <p> age of selected item is : {{selectedItem.age}} </p>
        <select ng-model="selectedItem" ng-options="item.name for item in items">
        </select>
    </div>

เอาท์พุทคำอธิบาย (สมมติรายการที่ 1 ที่เลือก):

selectedItem = {name: 'a', อายุ: 20} // [โดยค่าเริ่มต้นรายการที่เลือกจะเท่ากับรายการค่า]

selectedItem.age = 20

  • Case-2) เลือกเป็นเลเบลสำหรับค่าในอาร์เรย์:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <select ng-model="selectedItem" ng-options="item.age as item.name for item in items">
        </select>
    </div>

เอาท์พุทคำอธิบาย (สมมติว่ารายการที่เลือก 1): selectedItem = 20 // [เลือกส่วนคือitem.age ]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.