2015-03-07 2 views
2

Я пытаюсь создать тег Select с помощью AngularJS. Я использую ngOptions и ngModel для привязки данных.AngularJS select not binding при использовании значения как синтаксиса значения

Сейчас: Если скажем, у меня есть источник данных, как следует:

$scope.doesNotBind = [ 
 
     {ID: 12, Title: "12 - Does not bind"}, 
 
     {ID: 14, Title: "14 - Does not bind"}, 
 
    ]; 
 

 
$scope.doesNotBindModel = {ID: 14, Title: "14 - Does not bind"};
<select ng-options="value as value.Title for value in doesNotBind" ng-model="doesNotBindModel"> 
 
     <option value> </option> 
 
</select>

Это никогда не будет связывать. Но если я привяжу модель к этому; оно работает!

$scope.doesNotBindModel = $scope.doesNotBind[1];

я использую синтаксис неправильно или это ожидаемое поведение?

Я создал POC, чтобы полностью продемонстрировать то, что я говорю.

JSFiddle POC

Интересно, что, когда нет, как синтаксис (нет данных объекта привязки), он отлично работает (в демо-версии, а)

Спасибо!

Редактировать: Я предполагаю, что это ожидается, так как они по ссылке а?

+0

Обновленный ответ, основанный на ваших последних редактировать – mohamedrias

ответ

3

ngModel сравнивает по ссылке, а не значение. Так что если вы используете ng-options="value as value.Title for value in doesNotBind", то ваш doesNotBindModel должен быть:

JavaScript:

$scope.doesNotBindModel = $scope.doesNotBind[1]; 

Однако, если вы все еще хотите установить doesNotBindModel в JSON нотации, вы можете добавить track by value.ID к ng-options выражения, как это:

HTML:

<select ng-options="value as value.Title for value in doesNotBind track by value.ID" 
     ng-model="doesNotBindModel"> 
</select> 

Он также работает, добавив track by, но он не рекомендуется в документации Angular для ngOptions.

По причине за этим, пожалуйста, обратитесь к следующему примеру:

HTML:

<select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected"> 
    <option value="">---- not selected ----</option> 
</select> 

JavaScript:

$scope.values = [{ 
    id: 1, 
    label: 'aLabel', 
    subItem: { name: 'aSubItem' } 
}, { 
    id: 2, 
    label: 'bLabel', 
    subItem: { name: 'bSubItem' } 
}]; 

$scope.selected = { name: 'aSubItem' }; 

С целью сохранения выбора, выражение track by всегда применяется к элементу источника данных (до item в этом примере). Чтобы рассчитать, выбран ли элемент, мы делаем следующее:

  1. Применить track by к элементам в массиве. В примере: [1, 2]
  2. Применить track by к уже выбранному значению в ngModel.

В примере: Это не представляется возможным, так как track by относится к item.id, но выбранное значение из ngModel является {name: 'aSubItem'}. Таким образом, выражение track by применяется к неправильному объекту, выбранный элемент не может быть найден. <select> всегда возвращается к опции «не выбрано».

Живой пример: http://plnkr.co/edit/Hu5T1Vo3qTkrDqe5PHJy

+0

Привет. Спасибо за Ваш ответ. Я читал документацию, и я наткнулся на выражение треки. Почему это не рекомендуется? Говорят, не сочетать его с выбором как, то есть все. –

+0

Я прошел через это. Пример: <выберите нг-опция = «value.Title для значения в doesNotBind трека по value.ID» нг-модели = «doesNotBindModel»> –

+0

@AlbertHerd У меня есть обновить свой ответ, чтобы показать, почему документ Угловой сказал " Не используйте select as и track в одном выражении. Они не предназначены для совместной работы ». – zhimin

0

Это не связывает, потому что оба являются двумя разными объектами.

Когда вы создаете объект, ему назначается отдельная ячейка памяти.

var a = {}; 

var b = {}; 

если вы проверяете ли a === b, то он вернет вам ложь. Потому что оба являются двумя разными объектами.

Вот причина, почему

$scope.doesNotBindModel = {ID: 57, Title: "57 - Does not bind"}; 

не связывает тогда

$scope.doesBindModel = $scope.doesBind[3]; 

Потому что в последнем случае, вы имеете в виду тот же объект на основе его индекса.

+0

Да да я полностью понимаю, что этот вопрос является тот, который вы написали выше. Я искал больше пути для решения этой проблемы. Возможно, обходным путем является получение ссылки на объект при привязке. Это единственное логическое решение, которое я предполагаю. –

+0

Обход проблемы для? Если вы хотите предварительно выбрать конкретную опцию в поле выбора, то можете использовать ng-init или использовать способ индекса массива для установки определенного элемента. – mohamedrias

+0

Вы можете использовать ng-init и вызвать функцию. Там вы можете проверить конкретное условие и установить определенный элемент, выбранный в вашей ng-модели – mohamedrias

Смежные вопросы