AngularJS의 ng 옵션을 사용하여 선택 작업


442

다른 게시물에서 읽었지만 이해할 수 없었습니다.

배열이 있습니다.

$scope.items = [
   {ID: '000001', Title: 'Chicago'},
   {ID: '000002', Title: 'New York'},
   {ID: '000003', Title: 'Washington'},
];

다음과 같이 렌더링하고 싶습니다.

<select>
  <option value="000001">Chicago</option>
  <option value="000002">New York</option>
  <option value="000003">Washington</option>
</select>

또한 ID = 000002 인 옵션을 선택하고 싶습니다.

나는 select 를 읽고 시도했지만 이해할 수 없다.


Select2를 사용하는 것이 좋습니다 . AngularJS에 대한 지시문 도 있습니다 .
— hewstone


실제로 QuantumUI가 개발 한 순수한 AngularJS 솔루션이 있습니다 . http://quantumui.org/ 에서 더 많은 예제와 문서를 찾을 수 있습니다 .
— 라몬 드 런스

답변:


799

ngOptions가 작동 하려면 ngModel이 필요 하다는 점에 주목 해야 합니다. ng-model="blah""set $ scope.blah를 선택된 값으로 설정합니다."

이 시도:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

AngularJS의 문서에서 더 많은 내용을 볼 수 있습니다 (보지 못한 경우).

배열 데이터 소스의 경우 :

  • 배열의 값 레이블
  • 배열의 값 레이블로 선택
  • 배열의 값에 대한 그룹 별 레이블 그룹 = 배열의 값에 대한 그룹 별 레이블 그룹으로 선택

객체 데이터 소스의 경우 :

  • 객체에서 (key, value)에 대한 레이블
  • 객체에서 (key, value) 레이블로 선택
  • 객체의 (키, 값)에 대한 그룹 별 레이블 그룹화
  • 객체의 (키, 값)에 대해 그룹별로 레이블 그룹으로 선택

AngularJS의 옵션 태그 값에 대한 설명은 다음과 같습니다.

당신이 사용하는 경우 ng-options, 옵션 태그의 값은 항상 옵션 태그에 관한 배열 항목의 인덱스가됩니다 겨-옵션에 의해 작성 . AngularJS는 실제로 기본 유형뿐만 아니라 선택 컨트롤을 사용하여 전체 객체를 선택할 수 있기 때문입니다. 예를 들면 다음과 같습니다.

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});
<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

위의 방법으로 전체 객체를 $scope.selectedItem직접 선택할 수 있습니다. 요점은 AngularJS를 사용하면 옵션 태그에 무엇이 있는지 걱정할 필요가 없다는 것입니다. AngularJS가 처리하도록하십시오. 스코프의 모델에있는 것만 신경 써야합니다.

위의 동작을 보여주고 작성된 HTML을 보여주는 플런저입니다.


기본 옵션 다루기 :

기본 옵션과 관련하여 위에서 언급하지 않은 몇 가지가 있습니다.

첫 번째 옵션을 선택하고 빈 옵션을 제거하십시오.

ng-init모델을 (에서 ng-model) 반복하는 항목의 첫 번째 요소로 설정 하는 단순 을 추가하여이를 수행 할 수 있습니다 ng-options.

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.name for item in items"></select>

참고 : foo"거짓"으로 올바르게 초기화 되면 약간 미친 듯이 보일 수 있습니다. 이 경우 foo컨트롤러에서 초기화를 처리하고 싶을 것입니다.

기본 옵션 사용자 정의 :

이것은 조금 다릅니다. 여기서 빈 태그 속성으로 옵션 태그를 선택 항목의 하위 항목으로 추가하고 내부 텍스트를 사용자 정의하기 만하면됩니다.

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

참고 :이 경우 다른 옵션을 선택한 후에도 "빈"옵션이 그대로 유지됩니다. AngularJS에서 selects의 기본 동작에는 해당되지 않습니다.

선택 후 숨겨지는 사용자 정의 된 기본 옵션 :

값을 선택한 후 사용자 정의 된 기본 옵션을 제거하려면 ng-hide 속성을 기본 옵션에 추가 할 수 있습니다.

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>

3
그것들이 값의 인덱스임을 알 수 있습니다. 이것은 각도를 사용하여 객체를 선택 상자의 값으로 사용할 수있는 방법입니다. Angular는 선택 상자가있는 무대 뒤에서 많은 일을하고 있으며 옵션의 value 속성에 대해 걱정할 필요가 없습니다.
— Ben Lesh

1
설명서는 해당 사이트의 "선택"에 있습니다. docs.angularjs.org/api/ng.directive:select
— Ben Lesh

25
"... ngModels는 ngOptions가 작동하는 데 필요합니다 ..."는 문제의 핵심이었습니다. 좋은 대답입니다.
— tristanm

1
첫 번째 빈 옵션 ( <option value="?" selected="selected"></option>) 을 피할 수 있습니까?
— swenedo

4
마지막 사례 ( 선택 후 숨겨지는 사용자 정의 된 기본 옵션) 를 사용하려고하는데 몇 가지 문제가 있습니다. 대신 ng-if="foo"내가 사용 했어 ng-if=!foo다른 옵션을 선택하면 기본 빈 옵션을 숨 깁니다. 또한 기본 비어있는 옵션은 항상 콤보 목록의 맨 아래에 나타납니다. 콤보 목록의 시작 부분에 어떻게 넣을 수 있습니까?
— Fran Herrero

90

나는 AngularJS를 배우고 있으며 선택에도 어려움을 겪고있었습니다. 나는이 질문에 이미 답변되어 있지만 그럼에도 불구하고 더 많은 코드를 공유하고 싶었습니다.

내 테스트에는 자동차 제조업체와 자동차 모델의 두 가지 목록 상자가 있습니다. 일부 제조업체를 선택할 때까지 모델 목록이 비활성화됩니다. make 목록 상자에서 선택이 나중에 재설정되면 ( 'make 선택'으로 설정) 모델 목록 상자가 다시 비활성화되고 선택 항목도 재설정됩니다 ( 'Model 선택'으로). 모델은 단지 하드 코딩 된 동안 Make는 리소스로 검색됩니다.

JSON을 만듭니다.

[
{"code": "0", "name": "Select Make"},
{"code": "1", "name": "Acura"},
{"code": "2", "name": "Audi"}
]

services.js :

angular.module('makeServices', ['ngResource']).
factory('Make', function($resource){
    return $resource('makes.json', {}, {
        query: {method:'GET', isArray:true}
    });
});

HTML 파일 :

<div ng:controller="MakeModelCtrl">
  <div>Make</div>
  <select id="makeListBox"
      ng-model="make.selected"
      ng-options="make.code as make.name for make in makes"
      ng-change="makeChanged(make.selected)">
  </select>

  <div>Model</div>
  <select id="modelListBox"
     ng-disabled="makeNotSelected"
     ng-model="model.selected"
     ng-options="model.code as model.name for model in models">
  </select>
</div>

controllers.js :

function MakeModelCtrl($scope)
{
    $scope.makeNotSelected = true;
    $scope.make = {selected: "0"};
    $scope.makes = Make.query({}, function (makes) {
         $scope.make = {selected: makes[0].code};
    });

    $scope.makeChanged = function(selectedMakeCode) {
        $scope.makeNotSelected = !selectedMakeCode;
        if ($scope.makeNotSelected)
        {
            $scope.model = {selected: "0"};
        }
    };

    $scope.models = [
      {code:"0", name:"Select Model"},
      {code:"1", name:"Model1"},
      {code:"2", name:"Model2"}
    ];
    $scope.model = {selected: "0"};
}

27
친애하는 임의의 사용자. 이 질문과 대답은 다소 간단하고 복잡하지 않지만 코드 구성을 적절한 위치 (컨트롤러, 서비스, 템플릿, 데이터)로 구성하면 AngularJS의 우아함이 가장 단순하고 기본 형식으로 표시됩니다. 멋진 예입니다.
— Atticus

1
이것은 그것이 사용되는 방법이 아닙니다. 와 관련되지 않은 범위의 다른 변수를 ng-model가리켜 야합니다 . 의 예를 참조하십시오 docs.angularjs.org/api/ng/directive/ngOptionsmake
— 드미트리 Zaitsev

@DmitriZaitsev 나는 각도 문서 예제에서 설명 한 방식이 그것이 유일한 방법임을 의미하지 않기 때문에 틀렸다고 생각합니다. 왜 초보자에게 훌륭한 모범을 버리기보다는 이런 식으로 사용해서는 안된다고 생각하는지 설명하십시오.
— JRT

39

어떤 이유로 AngularJS는 나를 혼란스럽게 만듭니다. 그들의 문서는 이것에 꽤 끔찍합니다. 변형의 더 좋은 예를 환영합니다.

어쨌든 벤 레시의 대답에 약간의 차이가 있습니다.

내 데이터 수집은 다음과 같습니다.

items =
[
   { key:"AD",value:"Andorra" }
,  { key:"AI",value:"Anguilla" }
,  { key:"AO",value:"Angola" }
 ...etc..
]

지금

<select ng-model="countries" ng-options="item.key as item.value for item in items"></select>

여전히 옵션 값이 인덱스 (0, 1, 2 등)가되었습니다.

트랙 추가 하기 나를 위해 수정했습니다.

<select ng-model="blah" ng-options="item.value for item in items track by item.key"></select>

선택 목록에 객체 배열을 추가하려는 경우가 더 자주 발생하므로이 항목을 기억하겠습니다!

AngularJS 1.4에서는 ng-options를 더 이상 사용할 수 없지만 ng-repeat옵션 태그 에서 사용해야 합니다.

<select name="test">
   <option ng-repeat="item in items" value="{{item.key}}">{{item.value}}</option>
</select>

3
이 답변은 질문이 정확히 요구하는 것 같습니다. 다른 모든 대답은 독자에게 HTML이 생성되는 것을 걱정하지 말라고하지만 select 요소가 양식이면 매우 걱정합니다. 좋은 답변입니다!
— Keith

3
이것은 키뿐만 아니라 선택된 전체 객체를 모델에 저장한다는 것을 지적해야한다. 모델의 키만 원하는 경우 "item.key as item.value"버전을 사용하려고합니다. 모델에서 원하는 데이터가 아니라 HTML이 어떻게 생겼는지에 대해 숙지하면서 잠시 동안 혼란스러워했습니다.
— mhenry1384

@ mhenry1384 예, 전체 객체를 저장하는 것이 옳습니다. 나는 실제로 그 기능이 마음에 드는 경우 그 이상의 ID에 액세스 할 수 있기 때문에이 기능을 좋아합니다 (필요한 경우). 몽고 컬렉션으로 목록을 채울 때 선택한 항목의 속성이 필요합니다.
— Mattijs

2
내부에서 "ng-change"를 사용하여 어떻게 변화를 감지 할 수 option있습니까?
— Konstantinos Natsios

2
업데이트와 관련하여 이것은 올바르게 보이지 않습니다. ng-options는 1.5에서 여전히 잘 작동합니다. 문서에도 여전히 표시됩니다. docs.angularjs.org/api/ng/directive/select
— Jeremy A. West

15

질문은 이미 답변되었지만 (BTW, Ben이 제공하는 정말 훌륭하고 포괄적 인 답변) 완전성을 위해 다른 요소를 추가하고 싶습니다. 매우 편리 할 수도 있습니다.

Ben이 제안한 예에서 :

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

다음과 같은 ngOptions 양식이 사용되었습니다 select as label for value in array.

레이블 은 표현식이며 결과는 <option>요소 의 레이블입니다 . 이 경우 더 복잡한 옵션 레이블을 갖기 위해 특정 문자열 연결을 수행 할 수 있습니다.

예 :

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" 당신에게 같은 레이블을 제공합니다 Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"같은 당신이 레이블을 제공 Title (X)하는 경우, X제목 문자열의 길이입니다.

예를 들어 필터를 사용할 수도 있습니다.

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"Title (TITLE)Title 속성의 Title 값과 TITLE은 같은 값이지만 대문자로 변환되는 것과 같은 레이블을 제공합니다 .
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"Title (27 Sep 2015)모델에 속성이있는 경우 와 같은 레이블을 제공합니다.SomeDate

7

CoffeeScript에서 :

#directive
app.directive('select2', ->
    templateUrl: 'partials/select.html'
    restrict: 'E'
    transclude: 1
    replace: 1
    scope:
        options: '='
        model: '='
    link: (scope, el, atr)->
        el.bind 'change', ->
            console.log this.value
            scope.model = parseInt(this.value)
            console.log scope
            scope.$apply()
)
<!-- HTML partial -->
<select>
  <option ng-repeat='o in options'
          value='{{$index}}' ng-bind='o'></option>
</select>

<!-- HTML usage -->
<select2 options='mnuOffline' model='offlinePage.toggle' ></select2>

<!-- Conclusion -->
<p>Sometimes it's much easier to create your own directive...</p>

1
잊지 말라 당신 radix을 위해 parseInt: http://davidwalsh.name/parseint-radix
— GFoley83

6

각 옵션에 대한 사용자 지정 제목이 필요한 경우 ng-options해당 사항이 없습니다. 대신 ng-repeat옵션과 함께 사용하십시오 .

<select ng-model="myVariable">
  <option ng-repeat="item in items"
          value="{{item.ID}}"
          title="Custom title: {{item.Title}} [{{item.ID}}]">
       {{item.Title}}
  </option>
</select>

3

다음이 도움이 되길 바랍니다.

<select class="form-control"
        ng-model="selectedOption"
        ng-options="option.name + ' (' + (option.price | currency:'USD$') + ')' for option in options">
</select>

1

유용 할 수 있습니다. 바인딩이 항상 작동하는 것은 아닙니다.

<select id="product" class="form-control" name="product" required
        ng-model="issue.productId"
        ng-change="getProductVersions()"
        ng-options="p.id as p.shortName for p in products"></select>

예를 들어, REST 서비스에서 옵션 목록 소스 모델을 채 웁니다. 목록을 채우기 전에 선택한 값을 알고 설정했습니다. $ http로 REST 요청을 실행 한 후 list 옵션이 수행됩니다.

그러나 선택한 옵션이 설정되어 있지 않습니다. 알 수없는 이유로 shadow $ digest execution의 AngularJS는 선택된 바인드를 바인딩하지 않습니다. 선택한 것을 설정하기 위해 jQuery를 사용해야합니다. 중요합니다! 그림자 형태의 AngularJS는 ng-repeat 옵션으로 생성되는 attr "value"값에 접두사를 추가합니다. int의 경우 "숫자 :"입니다.

$scope.issue.productId = productId;
function activate() {
    $http.get('/product/list')
       .then(function (response) {
           $scope.products = response.data;

           if (productId) {
               console.log("" + $("#product option").length);//for clarity
               $timeout(function () {
                   console.log("" + $("#product option").length);//for clarity
                   $('#product').val('number:'+productId);

               }, 200);
           }
       });
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.