เริ่มต้นการเลือกด้วย AngularJS และ ng-repeat


135

ฉันกำลังพยายามให้ select-box เริ่มต้นด้วยตัวเลือกที่กรอกไว้ล่วงหน้าโดยใช้ ng-repeat กับ AngularJS 1.1.5 แต่การเลือกจะเริ่มต้นโดยไม่ได้เลือกไว้เสมอ นอกจากนี้ยังมีตัวเลือกว่างซึ่งฉันไม่ต้องการ ฉันคิดว่ามีผลข้างเคียงจากการไม่เลือกอะไร

ฉันสามารถใช้งานได้โดยใช้ ng-options แทน ng-repeat แต่ฉันต้องการใช้ ng-repeat สำหรับกรณีนี้ แม้ว่าตัวอย่างที่แคบลงของฉันจะไม่แสดง แต่ฉันก็ต้องการตั้งค่าแอตทริบิวต์หัวเรื่องของแต่ละตัวเลือกและไม่มีวิธีใดที่จะทำได้โดยใช้ตัวเลือก ng เท่าที่ฉันรู้

ฉันไม่คิดว่าสิ่งนี้เกี่ยวข้องกับขอบเขต AngularJs ทั่วไป / ปัญหาการสืบทอดต้นแบบ อย่างน้อยฉันก็ไม่เห็นอะไรชัดเจนเมื่อตรวจสอบใน Batarang นอกจากนี้เมื่อคุณเลือกตัวเลือกในการเลือกด้วย UI โมเดลจะอัปเดตอย่างถูกต้อง

นี่คือ HTML:

<body ng-app ng-controller="AppCtrl">
    <div>
        Operator is: {{filterCondition.operator}}
    </div>
    <select ng-model="filterCondition.operator">
       <option 
           ng-repeat="operator in operators" 
           value="{{operator.value}}"
       >
           {{operator.displayName}}
       </option>
    </select>
</body>

และ JavaScript:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]
}

JS Fiddle สำหรับสิ่งนี้: http://jsfiddle.net/coverbeck/FxM3B/2/


1
ngOption ถูกสร้างขึ้นเนื่องจากไม่มีวิธีที่สะอาดในการดำเนินการกับ ngRepeat ngRepeat unrolls หลังจากเลือกตัวเลือกแล้ว คุณลองตั้งค่า ngSelect บนตัวเลือกของคุณแล้วหรือยัง
TheSharpieOne

ใช่ ngSelected ใช้งานได้! ฉันจะโพสต์ JsFiddle ที่อัปเดตแล้ว
Charles O.

ควรสังเกตว่าใน AngualrJS 1.2 รหัสนี้ทำงานแตกต่างกัน - ไม่ได้สร้างองค์ประกอบ <OPTION> ว่างใหม่ แต่สามารถเลือกได้เฉพาะตัวเลือกแรกในกล่องรายการ คุณสามารถดูได้ที่นี่
VitalyB

คำตอบ:


230

ตกลง. หากคุณไม่ต้องการใช้วิธีที่ถูกต้องng-optionsคุณสามารถเพิ่มng-selectedแอตทริบิวต์ด้วยตรรกะการตรวจสอบเงื่อนไขสำหรับoptionคำสั่งถึงเพื่อให้การเลือกล่วงหน้าทำงานได้

<select ng-model="filterCondition.operator">
    <option ng-selected="{{operator.value == filterCondition.operator}}"
            ng-repeat="operator in operators"
            value="{{operator.value}}">
      {{operator.displayName}}
    </option>
</select>

Working Demo


37
ฉันจะให้เครดิตกับคุณเนื่องจากคุณคิดออกด้วยตัวคุณเองและทำตามตัวอย่างทั้งหมด แม้ว่าฉันจะไม่เห็นด้วยกับความคิดเห็นของคุณเกี่ยวกับ ng-options ว่าเป็น "วิธีที่ถูกต้อง" :) ฉันใช้ ng-options ด้วยตัวเองมาตลอด แต่สิ่งนี้จำเป็นต้องทำบางอย่างที่ ng-options ไม่รองรับเล็กอย่างที่เป็นอยู่ และเอกสารเชิงมุมบอกว่าคุณสามารถทำซ้ำได้เช่นกัน ขอบคุณ Charles
Charles O

ขอบคุณนั่นเป็นวิธีง่ายๆในการปิดใช้ตัวเลือกบางอย่าง
Dorian

11
ng-options นั้นถูกต้องตราบเท่าที่ usecases พอดีกับของคุณ คุณอาจต้องการแอตทริบิวต์ / คลาสเพิ่มเติมในฟิลด์ option / optgroup เป็นต้น
mystrdat

6
"วิธีที่ถูกต้อง" ใช้ไม่ได้ในบางครั้ง (เช่นหากคุณต้องการแปลสตริงที่เติมชื่อตัวเลือก)
btk

11
ฉันคิดว่านิพจน์ที่เลือกจะต้องไม่มี {{}}: ng-selected = "operator.value == filterCondition.operator"
mvermand

35

สำหรับแท็ก select เชิงมุมจะให้คำสั่ง ng-options ช่วยให้คุณมีกรอบเฉพาะในการตั้งค่าตัวเลือกและตั้งค่าเริ่มต้น นี่คือซอที่อัปเดตโดยใช้ ng-options ที่ทำงานได้ตามที่คาดไว้: http://jsfiddle.net/FxM3B/4/

อัปเดต HTML (โค้ดยังคงเหมือนเดิม)

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.value as operator.displayName for operator in operators">
</select>
</body>

3
สวัสดี Jeremy - ฉันกำลังพยายามทำสิ่งนี้โดยไม่มีตัวเลือก ng อย่างที่ฉันพูดในคำถามของฉันและตอบกลับ Shaun ฉันต้องการตั้งค่าแอตทริบิวต์ title ในแต่ละตัวเลือกและฉันไม่สามารถทำได้ด้วย ng-options เท่าที่ฉันรู้ ขอบคุณ Charles
Charles O.

9

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

นี่เป็น JSFiddle ทำงาน: http://jsfiddle.net/coverbeck/FxM3B/5/

ฉันยังอัปเดตซอเพื่อใช้แอตทริบิวต์ชื่อเรื่องซึ่งฉันได้ทิ้งไว้ในโพสต์เดิมของฉันเนื่องจากไม่ใช่สาเหตุของปัญหา (แต่เป็นเหตุผลที่ฉันต้องการใช้ ng-repeat แทน ng-options) .

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator">
   <option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option>
</select>
</body>

JS:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah'},
        {value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada'}
     ]
}

ขออภัยเกี่ยวกับการโพสต์เป็นความคิดเห็น ฉันไม่รู้สึกอยากทำเป็นตัวอย่างและฉันก็ไม่แน่ใจ 100% ว่าจะได้ผล มันเป็นเพียงลางสังหรณ์
TheSharpieOne

9

ความจริงที่ว่าเชิงมุมกำลังฉีดองค์ประกอบอ็อพชันว่างให้กับการเลือกคืออ็อบเจ็กต์โมเดลที่เชื่อมโยงกับอ็อบเจ็กต์โดยค่าเริ่มต้นจะมาพร้อมกับค่าว่างเมื่อเริ่มต้น

หากคุณต้องการเลือกตัวเลือกเริ่มต้นคุณสามารถตั้งค่าในขอบเขตในคอนโทรลเลอร์ได้

$scope.filterCondition.operator = "your value here";

ถ้าคุณต้องการตัวยึดตัวเลือกว่างสิ่งนี้ใช้ได้กับฉัน

<select ng-model="filterCondition.operator" ng-options="operator.id as operator.name for operator in operators">
  <option value="">Choose Operator</option>
</select>

2
เป็นสิ่งที่ดี แต่ Angular สร้างตัวเลือกว่าง จะหลีกเลี่ยงสิ่งนี้ได้อย่างไร?
MarceloBarbosa

1

ตามที่แนะนำคุณต้องใช้ ng-options และน่าเสียดายที่ฉันเชื่อว่าคุณต้องอ้างอิงองค์ประกอบอาร์เรย์เป็นค่าเริ่มต้น (เว้นแต่อาร์เรย์จะเป็นอาร์เรย์ของสตริง)

http://jsfiddle.net/FxM3B/3/

JavaScript:

function AppCtrl($scope) {


    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]

    $scope.filterCondition={
        operator: $scope.operators[0]
    }
}

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator.value}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.displayName for operator in operators">
</select>
</body>

คุณรู้สาเหตุและแน่ใจหรือไม่? เอกสารประกอบ ( docs.angularjs.org/api/ng.directive:select ) ระบุว่าคุณจำเป็นต้องใช้ตัวเลือก ng เท่านั้นเมื่อเชื่อมโยงกับค่าที่ไม่ใช่สตริง อย่างที่ฉันบอกว่าฉันต้องการใช้แอตทริบิวต์ title และไม่มีทางทำเช่นนั้นกับ ng-options อย่างเช่น <option title = "คำอธิบายที่ยาวมากสำหรับตัวเลือกนี้" ... > ขอบคุณ
Charles O.

ฉันเชื่อว่าหมายเหตุในเอกสารไม่ชัดเจนเล็กน้อยและจริงๆแล้วหมายความว่าคุณจะต้องใช้สตริงสำหรับโมเดลและมีอาร์เรย์ของสตริงสำหรับตัวเลือก หากคุณไม่ทราบว่าเหตุผลในการใช้แอตทริบิวต์ "title" คืออะไรฉันไม่เห็นใน W3C w3schools.com/tags/tag_option.aspและจำไม่ได้ว่าใช้จริงๆ คุณไม่สามารถเก็บคำอธิบายไว้ในวัตถุได้หรือไม่จากนั้นยังคงดึงข้อมูลดังกล่าวเนื่องจากนั่นคือสิ่งที่โมเดลถูกผูกไว้ในขณะนี้?
shaunhusain

ในหน้า W3C ที่คุณเชื่อมโยงหากคุณคลิกที่ลิงก์ Global Attributes คุณจะเห็นว่าแอตทริบิวต์ title ได้รับการสนับสนุนโดยองค์ประกอบตัวเลือก ฉันใช้แอตทริบิวต์ title เพื่อแสดงข้อความ "คำแนะนำเครื่องมือ" ดังนั้นหากคุณวางเมาส์เหนือตัวเลือกคุณจะได้รับคำอธิบายที่กว้างขึ้นว่าตัวเลือกนั้นหมายถึงอะไร มันเป็นสิ่งเล็กน้อย แต่ถ้าเป็นไปได้ก็คงจะดี
Charles O.

@CharlesO. ฉันอยากจะทำเหมือนคุณเป๊ะ ๆ ตั้งค่าวัตถุ (ค่าที่ไม่ใช่สตริง) แต่ฉันต้องการใช้หัวเรื่องในรายการตัวเลือกด้วย มีวิธีแก้ปัญหานี้หรือไม่ ดูเหมือนจะหาไม่เจอ ...
ร่วงโรย

1

หากคุณใช้ md-select และ ng-repeat ing md-option จากวัสดุเชิงมุมคุณสามารถเพิ่มng-model-options="{trackBy: '$value.id'}"เถ้าแท็ก md-select ที่แสดงในปากกานี้ได้

รหัส:

<md-select ng-model="user" style="min-width: 200px;" ng-model-options="{trackBy: '$value.id'}">
  <md-select-label>{{ user ? user.name : 'Assign to user' }}</md-select-label>
  <md-option ng-value="user" ng-repeat="user in users">{{user.name}}</md-option>
</md-select>

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