Инициализация выбора с AngularJS и ng-repeat


133

Я пытаюсь заставить select-box начать с предварительно заполненной опции, используя ng-repeat с AngularJS 1.1.5. Вместо этого выбор всегда начинается без выбора. У него также есть пустой параметр, который я не хочу. Я думаю, что есть побочный эффект ничего не быть выбранным.

Я могу заставить это работать, используя ng-options вместо ng-repeat, но я хочу использовать ng-repeat для этого случая. Хотя мой суженный пример не показывает этого, я также хочу установить атрибут title каждого параметра, и, насколько я знаю, сделать это невозможно с помощью ng-options.

Я не думаю, что это связано с общей проблемой AngularJs / прототипического наследования. По крайней мере, я не вижу ничего очевидного при проверке в Батаранге. Плюс, когда вы выбираете опцию в select с пользовательским интерфейсом, модель обновляется правильно.

Вот 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 разворачивается после выбора опции. Вы пробовали установить ngSelect для ваших опций
TheSharpieOne

Да! Выбранный ngSelected! Я выложу обновленный рабочий JsFiddle.
Чарльз О.

Следует отметить, что в AngualrJS 1.2 этот код работает по-другому - он не создает новый пустой элемент <OPTION>, однако он может выбрать только первую опцию в списке. Вы можете увидеть это здесь
VitalyB

Ответы:


226

ХОРОШО. Если вы не хотите использовать правильный путь 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 не поддерживает, как бы мало это ни было. И Angular Doc говорит, что вы также можете использовать jg-repeat. Спасибо, Чарльз
Чарльз О.

Спасибо, это был простой способ отключить некоторые опции.
Дориан

11
Параметры ng верны только в том случае, если их варианты использования соответствуют вашим. Вам могут понадобиться дополнительные атрибуты / классы в полях option / optgroup и т. Д.
mystrdat

6
«правильный путь» иногда не работает (например, если вы хотите перевести строки, которые заполняют имена опций)
btk

11
Я думаю, что ng-selected выражение должно быть без {{}}: ng-selected = "operator.value == filterCondition.operator"
mvermand

35

Для тега select angular предоставляет директиву 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
Привет Джереми - я пытаюсь сделать это без ng-параметров. Как я сказал в своем вопросе и в ответе Шону, я хотел бы установить атрибут title для каждой опции, и я не могу сделать это с помощью ng-options, насколько я знаю. Спасибо, Чарльз
Чарльз О.

9

Спасибо TheSharpieOne за указание на опцию ng-selected. Если бы это было опубликовано как ответ, а не как комментарий, я бы сделал это правильным ответом.

Вот рабочий JSFiddle: http://jsfiddle.net/coverbeck/FxM3B/5/ .

Я также обновил скрипку, чтобы использовать атрибут title, который я пропустил в моем исходном посте, поскольку это не было причиной проблемы (но именно поэтому я хочу использовать 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

Тот факт, что angular вводит пустой элемент option в select, заключается в том, что объект модели, связанный с ним по умолчанию, при инициализации получает пустое значение.

Если вы хотите выбрать опцию по умолчанию, вы можете установить ее в области видимости контроллера.

$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 = "Очень длинное описание этого выбора" ...> Спасибо.
Чарльз О.

Я считаю, что примечание в документах немного неясно и фактически означает, что вам придется использовать строку для модели и иметь массив строк для параметров. Если вы не возражаете против причин использования атрибута «title», я не вижу его на W3C w3schools.com/tags/tag_option.asp и не могу вспомнить его использование на самом деле. Не могли бы вы просто сохранить описание в объектах, а затем получить эти данные, поскольку это то, к чему сейчас привязана модель?
Shaunhusain

На странице W3C, на которую вы ссылаетесь, если вы щелкните ссылку Global Attributes, вы увидите, что атрибут title поддерживается элементом option. Я использую атрибут title только для отображения текста «всплывающей подсказки», чтобы при наведении указателя мыши на параметр можно было получить более подробное описание значения параметра. Это мелочь, но было бы неплохо иметь, если это возможно.
Чарльз О.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.