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.